Deserializing a "null" json response

3,591 views
Skip to first unread message

Patrick Steele

unread,
Jun 19, 2012, 6:22:44 PM6/19/12
to rest...@googlegroups.com
I'm running in to a problem deserializing a null json object.  I'm using the latest code from git (not from nuget).  This used to work with the JSON.Net library.

The problem occurs when the json response is simply "null" (without the quotes -- just the four characters n-u-l-l).  The JSON.Net deserializer handles this and returns null.  The JsonDeserializer in RestSharp successfully deserializes the string "null" to a null object, but then inside JsonDeserializer.Map(), the second parameter, which represents dictionary of data that has been deserialized, is null.  This causes a NullReferenceException when trying to find a matching property name a few lines inside the Map method:

var actualName = name.GetNameVariants(Culture).FirstOrDefault(n => data.ContainsKey(n));

I've made a change locally to prevent the exception:

var actualName = name.GetNameVariants(Culture).FirstOrDefault(n => data != null && data.ContainsKey(n));

But I'm not sure if that's a proper fix, or if there is a better place to make the check.  Maybe Map doesn't even need to be called if the deserialized string results in null?

Comments?

John Sheehan

unread,
Jun 20, 2012, 3:04:55 PM6/20/12
to rest...@googlegroups.com
I would use OnBeforeDeserialization to check for that value and either
swap out the content with something deserializer could handle or take
some other course of action.

Patrick Steele

unread,
Jun 25, 2012, 10:13:47 AM6/25/12
to rest...@googlegroups.com
That might be an option. But I don't see that the JsonSerializer
supports returning null. If I provide:

null

It gives me an error. If I try:

{}

It returns an empty object.

To be honest, I think JsonSerializer is correct (wrt the JSON spec) in
that "null" is considered a valid json VALUE but not a valid json
STRING. I think the newtonsoft deserializer that RestSharp used to
use was just being "nice" in allowing the string "null" to be parsed
to a null reference.

I may just have to go back to using the newtonsoft deserializer so I
can get proper null values.

---
Patrick Steele
http://weblogs.asp.net/psteele

Andrew Young

unread,
Jun 25, 2012, 12:35:21 PM6/25/12
to rest...@googlegroups.com
Another, less involved, approach would be to inherit from the current JsonSerializer and modify the behavior of it. Check for null before calling super.

Patrick Steele

unread,
Jun 25, 2012, 3:42:25 PM6/25/12
to rest...@googlegroups.com
Actually I'd have to encapsulate since Deserialize<T> is not virtual.
But still pretty easy:

public class NullSupportingJsonDeserializer : IDeserializer
{
public T Deserialize<T>(IRestResponse response)
{
if (response.Content == "null")
{
return default(T);
}
var deserializer = new JsonDeserializer
{
RootElement = this.RootElement,
Namespace = this.Namespace,
DateFormat = this.DateFormat
};
return deserializer.Deserialize<T>(response);
}

public string RootElement { get; set; }
public string Namespace { get; set; }
public string DateFormat { get; set; }
}

However, I notice the JsonDeserializer property no longer exists for
RestClient. Does this mean I need to manually register my
deserializer for all json types?

var client = new RestClient(restUri);
client.RemoveHandler("application/json");
client.RemoveHandler("text/json");
client.RemoveHandler("text/x-json");
client.AddHandler("application/json", new NullSupportingJsonDeserializer());
client.AddHandler("text/json", new NullSupportingJsonDeserializer());
client.AddHandler("text/x-json", new NullSupportingJsonDeserializer());

Thanks.

---
Patrick Steele
http://weblogs.asp.net/psteele


Andrew Young

unread,
Jun 25, 2012, 6:31:07 PM6/25/12
to rest...@googlegroups.com
Yes, but I don't think you need to remove it. AddHandler() will replace the handler that was previously registered for a given content type.
Reply all
Reply to author
Forward
0 new messages