Restsharp: Deserialize json object with less/more

2020-07-22 17:29发布

问题:

I'm using Restsharp to deserialize some webservice responses, however, the problem is that sometimes this webservices sends back a json response with a few more fields. I've manage to come around this so far by adding all possible field to my matching model, but this web service will keep adding/removing fields from its response.

Eg:

Json response that works:

{
    "name": "Daniel",
    "age": 25
}

Matching model:

public class Person
{
    public string name { get; set; }
    public int age { get; set; }
}

This works fine: Person person = deserializer.Deserialize<Person>(response);

Now suppose the json response was:

{
        "name": "Daniel",
        "age": 25,
        "birthdate": "11/10/1988"
}

See the new field bithdate? Now everything goes wrong. Is there a way to tell to restsharp to ignore those fields that are not in the model?

回答1:

If there's that much variation in the fields you're getting back, perhaps the best approach is to skip the static DTOs and deserialize to a dynamic. This gist provides an example of how to do this with RestSharp by creating a custom deserializer:

// ReSharper disable CheckNamespace
namespace RestSharp.Deserializers
// ReSharper restore CheckNamespace
{
    public class DynamicJsonDeserializer : IDeserializer
    {
        public string RootElement { get; set; }
        public string Namespace { get; set; }
        public string DateFormat { get; set; }

        public T Deserialize<T>(RestResponse response) where T : new()
        {
            return JsonConvert.DeserializeObject<dynamic>(response.Content);
        }
    }
}

Usage:

// Override default RestSharp JSON deserializer
client = new RestClient();
client.AddHandler("application/json", new DynamicJsonDeserializer());

var response = client.Execute<dynamic>(new RestRequest("http://dummy/users/42"));

// Data returned as dynamic object!
dynamic user = response.Data.User;

A simpler alternative is to use Flurl.Http (disclaimer: I'm the author), an HTTP client lib that deserializes to dynamic by default when generic arguments are not provided:

dynamic d = await "http://api.foo.com".GetJsonAsync();

In both cases, the actual deserialization is performed by Json.NET. With RestSharp you'll need to add the package to your project (though there's a good chance you have it already); Flurl.Http has a dependency on it.