Anton
Anton

Reputation: 9961

How to implement deserialization rules with RestSharp?

I am trying to write wrapper for Capsule CRM API using RestSharp.

I have problem with their API service. It returns JSON object when data is present and empty string when object is absent on CRM.

e.g., look on contacts:

{"organisation":{"id":"97377548","contacts":"","pictureURL":"","createdOn":"2016-02-08T14:27:12Z","updatedOn":"2016-02-08T14:27:12Z","lastContactedOn":"2013-12-03T21:00:00Z","name":"some name"}}

{"organisation":{"id":"97377548","contacts":{"email":{"id":"188218414","emailAddress":"someemail"},"phone":{"id":"188218415","type":"Direct","phoneNumber":"phone"}},"pictureURL":"","createdOn":"2016-02-08T14:27:12Z","updatedOn":"2016-02-08T14:27:12Z","lastContactedOn":"2013-12-03T21:00:00Z","name":"some name"}}

To match contacts I have class:

public class Contacts
{
    public List<Address> Address { get; set; }
    public List<Phone> Phone { get; set; }
    public List<Website> Website { get; set; }
    public List<Email> Email { get; set; }
}

and property Contacts in class that I am trying to match:

public Contacts Contacts { get; set; }

Everything works fine when API returns JSON object, but I get exception when I get empty string for contacts from API:

Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

How to avoid this problem? Is there any way to make conditional matching based on data that is returned from API? How I can tell RestSharp do not throw exception, just skip property if it can't match?

Upvotes: 1

Views: 1789

Answers (1)

NikolaiDante
NikolaiDante

Reputation: 18639

As you have control over your API, instead of returning "contacts":"" in the response, return "contacts":"{}" and that should avoid your error.


If you cannot alter the response from the API, you'll need to implement a custom serializer, as "" to object isn't supported by RestSharp.

This article summarizes how to use JSON.Net as the serializer, which would enable you to use whatever rules you needed to for your deserialization.

Article summary

First, implement ISerializer and IDeserializer interfaces in a NewtonsoftJsonSerializer class. This would give you full control on how the JSON is desierialized, so you can make "" work for an empty object.

Then, to use it on a request:

 private void SetJsonContent(RestRequest request, object obj)
 {
     request.RequestFormat = DataFormat.Json;
     request.JsonSerializer = new NewtonsoftJsonSerializer();
     request.AddJsonBody(obj);
 }

and to use it on a response:

private RestClient CreateClient(string baseUrl)
{
    var client = new RestClient(baseUrl);

    // Override with Newtonsoft JSON Handler
    client.AddHandler("application/json", new NewtonsoftJsonSerializer());
    client.AddHandler("text/json", new NewtonsoftJsonSerializer());
    client.AddHandler("text/x-json", new NewtonsoftJsonSerializer());
    client.AddHandler("text/javascript", new NewtonsoftJsonSerializer());
    client.AddHandler("*+json", new NewtonsoftJsonSerializer());

    return client;
}

Upvotes: 3

Related Questions