Reputation: 9961
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
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