0 Comments

When working with a mobile app you will often work with a backend, which if you are working with C# might very probably be a Web API backend. In this blog we will look at how we can consume and write to a Web API Controller that we can host on Azure. Why Azure? Because it is the easiest way of hosting a web service straight out of Visual Studio and if you happen to have a MSDN subscription you can do this all for free. For the client we will be using a Windows 10 Universal App which allows us to write a client for Desktop, Tablet and Phone.

The app we will be building will add the capability to read a list of people from a service and add a person to the existing. So we will see how we can read and write to a HTTP service.

The client

As a client we will be targeting Windows Phone (soon to be Windows Mobile again), Android and iOS. Our implementation of integrating with the backend we will perform in the Portable Class Library (PCL) which provides us the unique advantage of only having to write our backend service integration once.

PCL integration

In the PCL we will require the following NuGet packages:

Armed with the capabilities of now being able to communicate to a HTTP backend and serializing i.e. deserializing objects to and from JSON we can start implementing our communication layer by creating a HTTP client in the constructor. We usually only need one instance of the HTTP client as it will handle multiple requests and only spawn as many active connections as are reasonable over HTTP:

public class PersonService : IPersonService
{
    private HttpClient _httpClient;

    public PersonService()
    {
        _httpClient = new HttpClient();
    }

    // ... Person Service implementation
}

For reading over HTTP we should use the GET keyword which is provided by the HTTP client and is implemented as follows:

public async Task<IEnumerable<Person>> GetPeople()
{
    var result = await _httpClient.GetAsync(BASE_URI);
    var peopleJson = await result.Content.ReadAsStringAsync();

    return JsonConvert.DeserializeObject<IEnumerable<Person>>(peopleJson);
}

Note that if you are using a free website on Azure you can choose to run communications over SSL, the only thing you have to change for this is adding an s in the URI after http i.e. resulting in an https URI.

Writing to a HTTP service depends on the action we want to perform. Creating something new e.g. adding a new person to the existing person list, should be performed over a HTTP POST.  Implementing the post can be done as follows:

public async Task<bool> CreatePerson(Person person)
{
    var personJson = JsonConvert.SerializeObject(person);
    var content = new StringContent(personJson, Encoding.UTF8, "application/json");
    var result = await _httpClient.PostAsync(BASE_URI, content);

    return result.IsSuccessStatusCode;
}

The StringContent method has additional parameters to indicate to the server how the content can be interpreted. This is required to inform the backend service that the data we are sending is serialized as JSON. Not doing so would end in false information in the header which would prevent Web API to automatically deserialize the body.

Updating an existing person usually is done via PUT, which is similar to the CreatePerson method but contains an ID in the URI which usually corresponds with the ID from the Person which is set on the backend.

public async Task<bool> UpdatePerson(int id, Person person)
{
    var uri = Path.Combine(BASE_URI, id.ToString());

    var personJson = JsonConvert.SerializeObject(person);
    var content = new StringContent(personJson, Encoding.UTF8, "application/json");

    var result = await _httpClient.PutAsync(uri, content);

    return result.IsSuccessStatusCode;
}

As you can see implementing a Web service is quite straight forward with the HTTP Client and allows to easily create a backend integration for native clients that can be shared across platforms.

The UI

On the client side we now can invoke our portable service and display a list of people.

<Page
    x:Class="HttpClientSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HttpClientSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    DataContext="{Binding Main, Source={StaticResource Locator}}"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <GridView ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"></GridView>

        <AppBar VerticalAlignment="Bottom">
            <AppBarButton Icon="Add" Label="Add" Command="{Binding AddNewPerson}" />
        </AppBar>
    </Grid>
</Page>

In the ViewModel we can invoke the backend service to provide the data.

public class MainViewModel:ViewModelBase
{
    private readonly IPersonService _personService;
    private ObservableCollection<Person> _people;
    private Person _selectedPerson;

    public MainViewModel(IPersonService personService)
    {
        if (personService == null) throw new ArgumentNullException(nameof(personService));
        _personService = personService;
        _people = new ObservableCollection<Person>();
        ShowPerson = person => { };
        AddNewPerson = new RelayCommand(() => ShowPerson(0));
    }

    public ObservableCollection<Person> People => _people;
    public Action<int> ShowPerson { get; set; }

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            if (_selectedPerson == value) return;
            _selectedPerson = value;
            RaisePropertyChanged(nameof(SelectedPerson));
            if (_selectedPerson != null) ShowPerson(_people.IndexOf(_selectedPerson));
        }
    }

    public ICommand AddNewPerson { get; private set; }

    public async Task Init()
    {
        var people = await _personService.GetPeople();

        _people.Clear();

        foreach (var person in people)
        {
            _people.Add(person);
        }
    }
}

Adding a person means we have to add a further page to our client application that provides us with a form to enter the name and first name of a person. To keep things simple we will just use the same UI and identify via the navigation parameter if we have to create or update the person on the backend.

<Page
    x:Class="HttpClientSample.PersonDetail"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HttpClientSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    DataContext="{Binding Person, Source={StaticResource Locator}}"
    Loaded="PersonDetail_OnLoaded"
    mc:Ignorable="d">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBox Header="Firstname" Text="{Binding Firstname, Mode=TwoWay}"/>
        <TextBox Header="Lastname" Text="{Binding Lastname, Mode=TwoWay}"/>
        <Button Content="Save" Command="{Binding StoreCommand, Mode=TwoWay}" IsEnabled="{Binding HasPendingChanges}" HorizontalAlignment="Center" Margin="0,10"/>
    </StackPanel>
</Page>

The ViewModel is handling the integration with the PersonService from the PCL library:

public class PersonViewModel:ViewModelBase
{
    private readonly IPersonService _personService;
    private int _id;
    private string _firstname;
    private string _lastname;
    private bool _hasPendingChanges;

    public PersonViewModel(IPersonService personService)
    {
        if (personService == null) throw new ArgumentNullException(nameof(personService));
        _personService = personService;

        StoreCommand = new RelayCommand(StorePerson, () => true);
        HasPendingChanges = false;
    }

    public bool HasPendingChanges
    {
        get { return _hasPendingChanges; }
        set
        {
            if (value == _hasPendingChanges) return;
            _hasPendingChanges = value;
            RaisePropertyChanged(nameof(HasPendingChanges));
        }
    }

    public string Firstname
    {
        get { return _firstname; }
        set
        {
            if (value == _firstname) return;
            _firstname = value;
            HasPendingChanges = true;
            RaisePropertyChanged(nameof(Firstname));
        }
    }

    public string Lastname
    {
        get { return _lastname; }
        set
        {
            if (_lastname == value) return;
            _lastname = value;
            HasPendingChanges = true;
            RaisePropertyChanged(nameof(Lastname));
        }
    }

    public ICommand StoreCommand { get; set; }

    public async Task Init(int id)
    {
        _id = id;
        var person = id > 0 ? (await _personService.GetPeople()).ToList()[id] : new Person("", "");
        Firstname = person.FirstName;
        Lastname = person.LastName;
        HasPendingChanges = false;
    }

    private async void StorePerson()
    {
        HasPendingChanges = false;

        var person = new Person(Firstname, Lastname);

        if (_id > 0)
        {
            await _personService.UpdatePerson(_id, person);
        }
        else
        {
            await _personService.CreatePerson(person);
        }

        HasPendingChanges = false;
    }
}

Again integrating a PCL library is not difficult and requires no additional hoops to jump through. What we gain by putting our logic into the PCL is that we can reuse the code across multiple platforms.

The Controller

We will focus on the client part during this post but for getting an understanding of the bigger picture here is the controller we will be communicating with.

public class PersonController : ApiController
{
    private readonly static Lazy<IList<Person>> _people = new Lazy<IList<Person>>(() => new PersonService().GeneratePeople(1000), LazyThreadSafetyMode.PublicationOnly);
    // GET: api/Person
    public IEnumerable<Person> Get()
    {
        return _people.Value;
    }

    // GET: api/Person/5
    public Person Get(int id)
    {
        if (id < 0 || _people.Value.Count < id) return null;
        return _people.Value[id];
    }

    // POST: api/Person
    [HttpPost]
    public IHttpActionResult Post(Person value)
    {
        if (value == null) return BadRequest();

        _people.Value.Add(value);

        return CreatedAtRoute("DefaultApi", new { id = _people.Value.IndexOf(value) }, _people.Value.Last());
    }

    // PUT: api/Person/5
    [HttpPut]
    public IHttpActionResult Put(int id, [FromBody]Person value)
    {
        if (id < 0 || id >= _people.Value.Count()) return BadRequest();

        _people.Value[id] = value;

        return Ok(value);
    }

    // DELETE: api/Person/5
    public IHttpActionResult Delete(int id)
    {
        if (id < 0 || id >= _people.Value.Count()) return BadRequest();

        _people.Value.RemoveAt(id);

        return StatusCode(System.Net.HttpStatusCode.NoContent);
    }
}

internal class PersonService
{
    public IList<Person> GeneratePeople(int count)
    {
        var firstNames = new List<string>(count);
        var lastNames = new List<string>(count);

        for (int i = 0; i < count; ++i)
        {
            firstNames.Add(NameGenerator.GenRandomFirstName());
            lastNames.Add(NameGenerator.GenRandomLastName());
        }

        return firstNames.Zip(lastNames, (firstName, lastName) => new Person(firstName, lastName)).ToList();
    }
}

As you can see it is rather basic and through the static variable we have some sort of poor mans database. Do not use this way of storing data in a production environment!

Conclusion

In this post we saw how we can integrate a ASP.Net Web API server in a PCL. Thereby seeing how to read and write objects to a web service. Further we saw how we can display and enter the data on a Windows 10 client. The entire sample could have been written for Xamarin.iOS, Xamarin.Android or WPF which is exactly the sweet spot of writing your business logic in the PCL it does not matter what client you are intending to write now or in the future as long as the PCL allows you to integrate multiple client platforms.

You can find the entire sample project on NuGet.

0 Comments

message

Messages are a common pattern used in the Model View ViewModel (MVVM) pattern approach. They allow the ViewModel and Model to communicate with the view without having to couple them to it. Messages should generally be used to communicate changes within the system. Similar to events they provide a looser coupling and the message provides all the functionality of a C# object if need be. In this post I’ll show you how a message can be created, sent and finally how to register a handler within an object for a defined message.

Setting up the project

The demonstration project will be a Windows Phone 8.1 solution. You will have to install the MVVM Light NuGet package. We will have a simple view containing a label and a button:

<Page
x:Class="Messenger.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Messenger"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding InvokedMessage}" Style="{StaticResource MessageDialogContentStyle}"
Margin="0,10" />
<Button Content="Invoke Service" HorizontalAlignment="Center" Command="{Binding InvokeServiceCommand}" Width="200" Margin="0,10" />
</StackPanel>
</Page>

The button triggers a command in the ViewModel, which invokes an update of the service:

private void InvokeService()
{
CanInvokeService = false;

_sampleService.NonBlockingAsyncMethod();
}

The service is a async void method which means it can not be awaited. After the delay has passed a message shall be sent any receiver:

public async void NonBlockingAsyncMethod()
{
_invokedCount += 1;
await Task.Delay(3000);

GalaSoft.MvvmLight.Messaging.Messenger.Default.Send(new SampleMessage(_invokedCount));
}

So lets see how the message is implemented.

Creating a message

A message is a POCO (Plain Old CLR Object) that inherits from MessageBase. It is up to the developer how many properties or even functions shall be added to the message. In general a message should be treated as a Data Object.

internal class SampleMessage:MessageBase
{
public SampleMessage(int invokedCount):base()
{
InvokedCount = invokedCount;
}

public int InvokedCount { get; set; }
}

For our sample we will simply add a count property that indicates the number of calls the service has been invoked.

Sending a message

Sending a message is simply done by invoking the Send method on the default Messanger, as it is done in the NonBlockingAsyncMethod in the SampleService:

GalaSoft.MvvmLight.Messaging.Messenger.Default.Send(new SampleMessage(_invokedCount));

So now all we have to do is register our receivers.

Subscribing/Registering the message receiver

On the view model we can register a handler that receives the message and updates the label with an according call:

GalaSoft.MvvmLight.Messaging.Messenger.Default.Register<SampleMessage>(this, ReceiveSampleMessage);

 

Which is done in the MainViewModel.

Conclusion

Messaging allows to decouple objects that need to communicate with one another. In our sample the service communicates with the ViewModel but does not have any direct reference of the ViewModel and therefore is fully decoupled of it. Messaging can be a great help in writing maintainable code but be advised that though this method does allow to decouple objects it also adds complexity and therefore passing a method as call back function might be sometimes the more straight forward way of communicating to a developer.

You can find the entire code on GitHub.

References

Laurent Bugnion who is the creator and maintainer of the MVVM Light framework.

0 Comments

Xamarin Platform

Xamarin founded in 2011 (former Mono) has been enabling C# developers to write mobile apps for Android and iOS. Xamarin provides full access to the entire SDKs of the targeted platforms and therefore allows to build native apps that perform like apps written in the platform default language e.g. Java, Swift or Objective-C, look like native apps and provide a user experience like native apps. This makes it an ideal candidate to write high quality apps which provide a great user experience without having to rewrite the entire application for each targeted platform. See Christoph Rehmann’s post on an overview of Xamarin and a comparison to Hybrid and web applications in general.

Anatomy of a Xamarin application

The standard approach for writing Xamarin applications is to write The common approach of writing Xamarin apps allows to share all the platform independent code.

XamarinStack

But as soon as it comes down to writing the UI for the application or integrating native features such as a Widget or Push Notifications the developer will integrate those using the platform specific SDKs which usually are different for each platform. This is a logical coincidence for getting the full native SDKs and therefore also means that developers must embrace the platform designs and principals or else frustrated users will follow. For certain apps this approach makes a lot of sense as it allows to share the logic and present the user a native user interface that acts the way she knows and is accustomed to. Plus it let’s you design those fancy and unique UIs that really can set you apart from the competition. But what about the following two examples?

  • But in many apps there are screens that look pretty much the same across multiple platforms, this can be ranging from an about page, manual, checkout or login screen. With the standard Xamarin approach these views have to be written for each platform, though one might argue that apart from some small tweaks the UI stays greatly the same.
  • Other apps just want to allow the user aka employee to get stuff done while he is on the go. These apps are often form based applications that have the demand of getting out of the users way, work offline and be available on different form factors and in case of a Bring Your Own Device (BYOD) policy platforms.

For these kind of cases a lot of people start looking towards a HTML based or hybrid approach. Making a decision between native i.e. Xamarin and Hybrid is a discussion on it’s own. The gist is that Hybrid applications in theory allow you to not only share your business logic but also your UI, on the UI part you might end up writing code specific for each platform but as stated this shall not be the focus of this post. That being said wouldn’t it be great if for simple UIs we had the possibility to share the UI code across platforms? And this is exactly where Xamarin.Forms comes in.

Meet Xamarin.Forms

Given the requirements stated above, paired with the desire of relying on native applications with native user controls that not only looks like a native app but also performs the way the user expects an app to work is exactly the reason why Xamarin.Forms was created. Xamarin.Forms allows you to write your UI once and share it across multiple platforms resulting in a maximum of code being shared:

Xamarin.Forms

The UI is still fully native and allows the developer to create a native app experience. But instead of writing the UI over and over for each platform the UI is only created once and is then matched to the native controls and layouts that exist on Android, iOS and Windows (Phone). And the best part is that one can mix it with the standard Xamarin approach. So even if one is going for a unique design experience the simpler screens can still be written in Xamarin.Forms and shared across the platforms.

The UI

The UI is usually written in the Portable Class Library (PCL) which is a special library that allows code to be shared across C# library stacks such as Phone/Tablet Store Apps, .Net, ASP.Net, X-Box and with Xamarin iOS and Android. So writing your code in the PCL allows you to share the UI code to all platforms which are supported by the Xamarin.Forms framework which are:

  • iOS
    • iPhone/iPod
    • iPad & iPad Mini
  • Android
    • Phone
    • Tablet
  • Windows
    • Widnows Phone 8 & 8.1
    • Windows 8.1

The UI usually needs some tweaking when moving from one form factor to another but again some controls could be shared and with Xamarin.Forms they can be shared not only across factors but platforms. From a UI stand point Xamarin.Forms comes with limitations. The controls are a limited set and though they theoretically do allow to create a custom design it is currently not advised as the rendering will perform not as well than it’s Windows, Xamarin.iOS or Xamarin.Android UI counterparts.

Generally speaking as long as you are creating an app that can be created with standard components with minimal modifications Xamarin.Forms should serve you just fine.

That being said it is possible to write a part of the UI with Xamarin.Forms and integrate it with native screens. So one could start out with a Xamarin.Forms app and when you start bumping into performance issues on certain screens you can rewrite it for each platform and benefit from creating customized UIs and integrate to standard components such as login forms with Xamarin.Forms.

Integrating the platform

So Xamarin.Forms is an abstraction layer that allows developers to create UI’s once and then translates the UI to native UI controls on the specific platform. But what if you want to access the SDK of a given platform e.g. push notifications. With other cross platform approaches this often means you have to use a plugin that provides you the functionality for the platform. But as Xamarin.Forms builds on the full Xamarin stack you have full access to the SDK of the platform and are not limited by available plugins or SDK restrictions.

Limitations

So apart from not being great for designing highly customized apps are there any further limitations to Xamarin.Forms? I guess one of the biggest limitations to Xamarin.Forms at the moment is it’s age. It came out on 28. May 2014 and still is a 1.0 product, which are known for having some rough edges and Xamarin.Forms is no exception. So there are some issues that one may be bound to run into e.g. no UI designer, performance on data heavy views and the usual bugs that accompany V1.0 releases. That being said there is a huge interest in the Framework and it is already being used by a wide variety of apps i.e. fields. And given the recent efforts and releases of the team I believe Xamarin.Forms is a great option for certain types of applications.

Conclusion

We saw that Xamarin.Forms allows to develop native mobile apps for multiple platforms and thereby share the business logic and UI. Xamarin.Forms allows to write apps with XAML and is a great starting point for apps or writing prototypes. Because it integrates fully into the existing Xamarin stack there is no downside and switching between native UIs and Xamarin.Forms is a possibility for developers.

If your interested in the basic setup of a Xamarin.Forms app, here is a Hello World app that will run on Windows Phone, iOS and Android and shares all the XAML UI code.

This post was originally posted on the blog of Noser Engineering.

1 Comments

JSON Logo i.e. blog post logo

Though frowned upon often due to overuse inheritance remains a powerful and (when used correctly) great feature of an object oriented programming language such as C#. But when it comes down to serializing inheritance object structures i.e. deserializing them on the other side things tend to get hairy. The post will show you how serialization and deserialization of inheritance related objects can be performed with JSON.Net.

So lets have a look at the project setup. The server will be your standard ASP.Net Web API restful web service that comes with JSON.Net out of the box. On the client side we will be using consuming the service from a Portable Class Library PCL that will be able to run with most C# stacks e.g. Windows Store, .Net, Xamarin.iOS, Xamarin.Android etc.. I’ll be using a Xamarin.Forms app but the code will run just fine in your ever day WPF app. The basic system setup is the client calls the server for data, the server returns the data serialized as JSON which will then be deserialized on the client and then used to display the information to the user.

System overview showing communication flow from the client to the server and back via JSON serialized data.

So lets have a look how it works in more detail.

Setting up the project

Lets start with looking at the server which mainly exists of a controller:

public class InheritanceController : ApiController
{
// GET: api/Inheritance
public IEnumerable<ParentClass> Get()
{
return new ParentClass[] {new ParentClass(), new ChildClass()};
}
}

The controller creates a list of ParentClasses and ChildClasses before serializing them back to the caller.

public class ParentClass
{
public virtual string Title
{
get { return "Parent"; }
}

public virtual string Descirption
{
get { return "Hello from the parent."; }
}
}

public class ChildClass:ParentClass
{
public override string Title
{
get { return "Child"; }
}

public override string Descirption
{
get { return "The child says hi..."; }
}

public string ChildSecret
{
get { return "42"; }
}
}

So not a lot of magic going as you can see on the server side. So lets have a look at the client. In the PCL we will use the HTTP Client NuGet package to call the server and the JSON.Net package to deserialize the data from the server.

Nuget Package overview on the client showing JSON.NET, Microsoft BCL Build Components, MVVMLIght libraries only, Microsoft HTTP Client Libraries and Xamarin.Forms packages

On the client we will display the data in a list, you can see the UI code in the MainPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="InheritanceJsonSerialization.Client.Views.MainPage">
<Grid>
<ListView ItemsSource="{Binding DataItems}" ItemSelected="ListView_OnItemSelected" />
<ActivityIndicator IsRunning="{Binding IsLoading}" IsEnabled="{Binding IsLoading}" IsVisible="{Binding IsLoading}"/>
</Grid>
</ContentPage>

In the HttpHandler class in the GetData method the data is requested from the server and then deserialized.

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using InheritanceJsonSerialization.Client.Models;
using Newtonsoft.Json;

namespace InheritanceJsonSerialization.Client.Services.Http.Impl
{
public class HttpHandler:IHttpHandler
{
private readonly HttpClient _httpClient;

public HttpHandler()
{
_httpClient = new HttpClient();
}

public async Task<IEnumerable<ParentClass>> GetData()
{
// Ensure that uri matches the service backend you are calling
//const string uri = "http://localhost:52890/api/inheritance";
const string uri = "https://inheritancejsonserializationweb.azurewebsites.net/api/inheritance";

var httpResult = await _httpClient.GetAsync(uri);
var jsonContent = await httpResult.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent);

return result;
}
}
}

Now when we deserialize the information on the client we run into the problem that the type information is not passed on to the client and therefore all objects deserialized are of type ParentClass.

Serializing with type information

Luckely JSON.Net allows us to easily include the type information when we serialize the type. On the server in the Register method within the WebApiConfig class we can setup how JSON.Net serializes objects:

public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.All;

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}

Now the information will be serialized in the JSON string:

{
"$type": "InheritanceJsonSerialization.Models.ParentClass[], InheritanceJsonSerialization",
"$values": [
{
"$type": "InheritanceJsonSerialization.Models.ParentClass, InheritanceJsonSerialization",
"Title": "Parent",
"Descirption": "Hello from the parent."
},
{
"$type": "InheritanceJsonSerialization.Models.ChildClass, InheritanceJsonSerialization",
"Title": "Child",
"Descirption": "The child says hi...",
"ChildSecret": "42"
}
]
}

On the client side we will have to do a bit more work to get deserialization working.

Deserializing with Type information

For deserializing with type information you might have already found the following line of code that will trigger JSON.Net to check for the type information and try to deserialize it according to the information present in the JSON string.

            JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent, new JsonSerializerSettings{TypeNameHandling = TypeNameHandling.All});

The problem here is that all will go well when you serialize and deserialize from the same binary/namespace but in this setup (which I regard as the common setup) you will get an exception as the namespace will not exist i.e. be different on the client than on the server. To solve this issue we have to write a SerializationBinder that inherits from the DefaultSerializationBinder as follows:

public class InheritanceSerializationBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
switch (typeName)
{
case "InheritanceJsonSerialization.Models.ParentClass[]": return typeof(ParentClass[]);
case "InheritanceJsonSerialization.Models.ParentClass": return typeof(ParentClass);
case "InheritanceJsonSerialization.Models.ChildClass[]": return typeof(ChildClass[]);
case "InheritanceJsonSerialization.Models.ChildClass": return typeof(ChildClass);
default: return base.BindToType(assemblyName, typeName);
}
}
}

This will simply map the server namespace to local types. Finally we can update the GetData method in the HttpHandler class:

public async Task<IEnumerable<ParentClass>> GetData()
{
// ...
var result = JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent, new JsonSerializerSettings{TypeNameHandling = TypeNameHandling.All, Binder = new InheritanceSerializationBinder()});

return result;
}

And now when we deserialize the list the ChildClass will be correctly identified i.e. the list will be preserved through deserialization.

Conclusion

In this post you saw how inheritance hirarchies can be correctly serialized and deserialized on the client using JSON.Net. By doing so we had to configure our ASP.Net Web API and add handling mechanisms on the client side. I hope this post is of any help and please let me know if I may have mist anything Smile

You can find the code on GitHub.

0 Comments

StorageImage

A lot of applications have to persist application data or state. When developing mobile applications with C# such as for Windows or with Xamarin for iOS and Android it is a common approach to share your business logic and backend implementations in the Portable Class Library (PCL). In this blog post we’ll look at how we can also implement storage within the PCL and therefore will only need to implement the storage services once. We will be focusing on the following topics:

  1. Setting up the project
  2. Storing and loading objects to files
  3. Storing/using binary data such as images

So lets start off by setting up the project. I’ll be demonstrating the sample with a Xamarin.Forms project as it allows me to quickly develop, deploy and test an app on all three major mobile platforms. But as the code is in the PCL you can use the exact same approach to implement the system in Windows Store, WPF etc. applications.

Setting up the project

Lets create an app that lists Companies by name, URL and displays the company logo. To do this we will create a view that will display the content as follows:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinFormsOfflineStorage.Views.MainPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Text="Refresh" Command="{Binding UpdateCompaniesCommand}"></Button>
<ListView ItemsSource="{Binding Companies}" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Name}" ImageSource="{Binding ImageUri}" Detail="{Binding ImageDescription}"></ImageCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ActivityIndicator Grid.Row="1" IsRunning="{Binding IsLoadingData}"></ActivityIndicator>
</Grid>
</ContentPage>

The data is provided by a View Model that is based upon the MVVM Light framework by Laurent Bugnion. I wrote a post a while ago on how to get started with MVVM Light and Xamarin.Forms.

public class MainViewModel:ViewModelBase
{
private readonly ICompanyService _companyService;
private bool _isLoadingData;

public MainViewModel(ICompanyService companyService)
{
if (companyService == null) throw new ArgumentNullException("companyService");
_companyService = companyService;

Companies = new ObservableCollection<Company>();
IsLoadingData = false;
UpdateCompaniesCommand = new RelayCommand(UpdateCompanies, () => !IsLoadingData);
}

public bool IsLoadingData
{
get { return _isLoadingData; }
set
{
if (value == _isLoadingData) return;
_isLoadingData = value;
RaisePropertyChanged(() => IsLoadingData);
}
}

public ObservableCollection<Company> Companies { get; set; }

public ICommand UpdateCompaniesCommand { get; set; }

public async Task Init()
{
await UpdateCompaniesList();
}

private async void UpdateCompanies()
{
IsLoadingData = true;

await _companyService.UpdateCompanies();
await UpdateCompaniesList();

IsLoadingData = false;
}

private async Task UpdateCompaniesList()
{
var companies = await _companyService.GetCompanies();

Companies.Clear();

foreach (var company in companies)
{
Companies.Add(company);
}
}
}

Which calls a CompanyService that calls the backend:

// ...

public async Task UpdateCompanies()
{
// URL should point to where your service is running
const string uri = "http://offlinestorageserver.azurewebsites.net/api/values";
var httpResult = await _httpClient.GetAsync(uri);
var jsonCompanies = await httpResult.Content.ReadAsStringAsync();

var companies = JsonConvert.DeserializeObject<ICollection<Models.Company>>(jsonCompanies);
_companies = companies;
}

// ...

And provides a list of companies:

public IEnumerable<Models.Company> GetCompanies()
{
return _companies;
}

Now lets look on how we can store this list to the “disk” and display the information even if the app is started when there is no connection to the backend.

Enabling storage access in the PCL

Thanks to Daniel Plaisted accessing the file storage from within the PCL of your applications is actually really easy. All that is left to do for us is installing the NuGet package PCL Storage. Ensure that you install it not only for the PCL but only for the platforms you are targeting with your app:

PclStorageNugetInstall

Before we store lets just still quickly have a look at where we actually want to store the files. The PCL storage provides a start location which can be accessed by calling the FileSystem.Current.LocalStorage property. This will return an IFolder object which can be allows navigating to further folders by invoking the GetFolder method, alternatively the CreateFolder method can also be used with the collision option OpenIfExists, I generally use the second approach as it allows to write less code. So if we want to store our data in a folder within the root location of the local storage it would be done as follows:

private static async Task<IFolder> NavigateToFolder(string targetFolder)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder folder = await rootFolder.CreateFolderAsync(targetFolder,
CreationCollisionOption.OpenIfExists);

return folder;
}

As you can see the PCL Storage embraces the Async/Await pattern nicely and therefore will not block your app i.e. UI when working against the file system. Now lets get down to storing some data.

Persist an object

Now lets first store the list of objects we receive from our service into a file. As I’m already using JSON.Net for deserializing the data that comes from our service I’ll be using this library to serialize our objects to a JSON string and then store the now text data to a file in the SerializeCompanies method:

private static async Task SerializeCompanies(IFolder folder, ICollection<Models.Company> companies)
{
IFile file = await folder.CreateFileAsync(CompaniesFileName, CreationCollisionOption.ReplaceExisting);
var companiesString = JsonConvert.SerializeObject(companies);
await file.WriteAllTextAsync(companiesString);
}

As you can see files are created similarly to folders but differ in the collision option. It generally is a generally easier to handle merging of data in the C# memory world itself (given that the list is not to large for this) and then simply overwriting the preexisting cache.

Loading the data object

We can now update the GetCompanies method to return the list when we call it.

public async Task<IEnumerable<Models.Company>> GetCompanies()
{
return _companies ?? (_companies = await ReadCompaniesFromFile());
}

Once the data has been persisted by the website we do no longer require an internet connection to present the user with the information. And we can simply read them from a file as in ReadCompaniesFromFile:

private async Task<IEnumerable<Models.Company>>  ReadCompaniesFromFile()
{
var folder = await NavigateToFolder(CompaniesFolder);

if ((await folder.CheckExistsAsync(CompaniesFileName)) == ExistenceCheckResult.NotFound)
{
return new List<Models.Company>();
}

IFile file = await folder.GetFileAsync(CompaniesFileName);
var jsonCompanies = await file.ReadAllTextAsync();

if (string.IsNullOrEmpty(jsonCompanies)) return new List<Models.Company>();

var companies = JsonConvert.DeserializeObject<IEnumerable<Models.Company>>(jsonCompanies);

return companies;
}

Now the object data is persisted but we haven’t yet stored the images which is not text data but binary data. So lets see how we can store images to the file system.

Store binary data

To store the images we will have to get the images and store the binary data from the web to a file. This is done using the file stream of the opened file in the StoreImagesLocallyAndUpdatePathmethod:

private async Task StoreImagesLocallyAndUpdatePath(IFolder folder, IEnumerable<Models.Company> companies)
{
foreach (var company in companies)
{
var file = await folder.CreateFileAsync(company.Name + ".jpg", CreationCollisionOption.ReplaceExisting);
using (var fileHandler = await file.OpenAsync(FileAccess.ReadAndWrite))
{
var httpResponse = await _httpClient.GetAsync(company.ImageUri);
byte[] imageBuffer = await httpResponse.Content.ReadAsByteArrayAsync();
await fileHandler.WriteAsync(imageBuffer, 0, imageBuffer.Length);

company.ImageUri = file.Path;
}
}
}

Streams should always be disposed or else memory leaks will occur so the stream is wrapped in a using block. For storing the binary data we download the image via the URL provided and read the content into a byte array which allows us to easily pass it into the stream so it can get stored. Finally we replace the ImageUri data in the POCO (Plain Old CLR Object) before it gets serialized.

I recommend that you use the file endings according to the data you are storing. Certain containers rely on the information so as long as the good practice is kept up we are not running the risk of having to debug a strange error of information not showing up on the screen.

Loading images

Now we could load the images back into memory but as images are somewhat a special case the local path / ImageUri alone is enough to be set in the image control. So we actually do not have to change any code in the UI or add any additional handling as the image control will simply now load the image from the local storage.

Conclusion

In this post we saw how we can setup our projects to store files directly out of the PCL. We stored a data object i.e. text data to a file and proceeded to store an image/binary data. I think a big thank you is due to Daniel Plaisted as his work really streamlines persisting data with from the PCL.

You can find the entire code on GitHub.

References

Title Image by Dr. Hannes Grobe under Creative Commons V3