Skip to content

Serialization and Deserialization With ISerializationAdapter

Christian Findlay edited this page Aug 9, 2021 · 12 revisions

Clients achieve serialization and deserialization with implementations of ISerializationAdapter. RestClient.Net can use any serialization method. It means that RestClient.Net does not depend on any external serialization libraries other than the default System.Text.Json serialization. The aim is to follow the dependency injection pattern and not force developers to download libraries that they don't need.

All platforms other than .NET 4.5 depend on the System.Text.Json namespace. .NET Core automatically has this namespace but other platforms require the NuGet dependency. .NET 4.5 does not support this NuGet package and therefore does not have a default serialization adapter. If you target .NET 4.5 and require JSON serialization, you must manually add it. This is the reason that the Client constructor is different for .NET 4.5. If you do not specify a serialization adapter as an argument to the constructor on .NET 4.5 you will see this exception:

var client = new Client(null);

System.ArgumentNullException: 'Value cannot be null. Parameter name: serializationAdapter'

To ensure that your code is compatible between .NET 4.5 and other platforms, you should use JSON serialization that exists on .NET 4.5 such as the Newtsonsoft serialization adapter.

JSON Serialization

Newtonsoft

RestClient.Net does not come with the most popular JSON library Newtonsoft.Json by default. Developers can add JSON support with Newtsonsoft by adding the Newtsonsoft NuGet package and copying the code for the adapter into the project.

using Newtonsoft.Json;
using System.Text;

namespace RestClient.Net
{
    public class NewtonsoftSerializationAdapter : ISerializationAdapter
    {
        #region Implementation
        public TResponseBody? Deserialize<TResponseBody>(byte[] responseData, IHeadersCollection? responseHeaders)
        {
            //Note: on some services the headers should be checked for encoding 
            var markup = Encoding.UTF8.GetString(responseData);

            object markupAsObject = markup;

            return typeof(TResponseBody) == typeof(string) ? (TResponseBody)markupAsObject : JsonConvert.DeserializeObject<TResponseBody>(markup);
        }

        public byte[] Serialize<TRequestBody>(TRequestBody value, IHeadersCollection requestHeaders)
        {
            var json = JsonConvert.SerializeObject(value);

            var binary = Encoding.UTF8.GetBytes(json);

            return binary;
        }
        #endregion
    }
}

Usage

var client = new Client(new NewtonsoftSerializationAdapter(), new Uri("https://restcountries.eu/rest/v2/"));
var response = await client.GetAsync<List<RestCountry>>();

Default JSON Serialization Adapter

RestClient on .NET Core 3.0 introduces the default serialization method which uses System.Text.Json. This library comes packaged with .NET Core but doesn't exist on other platforms. Over time, this will most likely become the recommended serialization adapter, but there are some differences between this library and Newtsonsoft so it remains slightly experimental until it is accepted as a replacement for Newtsonsoft by the community.

This is an example. Notice that it does not require a serialization adapter as part of the constructor.

public async Task GetDefaultSerializationRestCountries()
{
    using var client = new Client("https://restcountries.eu/rest/v2/".ToAbsoluteUrl());
   var countries = await client.GetAsync<List<RestCountry>>();
}

This serialization adapter is also recommended if the backend is an ASP Web API because System.Text.Json is compatible. Note that by default, this adapter uses case insensitive JSON properties. But, using the case-sensitive option will yield better performance.

Other Serialization

Protobuf is a recommended serialization method. Please read this article about Protobuf serialization.