10

I have the following code:

public void GetJson()
{
    RestRequest request = new RestRequest(Method.GET);

    var data = Execute<Dictionary<string, MyObject>>(request);
}

public T Execute<T>(RestRequest request) where T : new()
{
    RestClient client = new RestClient(baseUrl);
    client.AddHandler("text/plain", new JsonDeserializer());

    var response = client.Execute<T>(request);

    return response.Data;
}

The problem is that sometimes the response will be an empty json array []. And when I run this code I get the following exception: Unable to cast object of type 'RestSharp.JsonArray' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

Is there a way to gracefully handle this?

xan
  • 7,440
  • 8
  • 43
  • 65
Thomas
  • 5,888
  • 7
  • 44
  • 83
  • Do you have any chance of changing what the response is from the server? It should have returned you an empty object {} instead of an empty array []. The two are not compatible even in JSON. – Joel Lucsy Mar 20 '13 at 20:45
  • I can think of simple hacks but that's about it. – evanmcdonnal Jul 31 '13 at 02:10
  • @Thomas: Anyone have any more thoughts on this? Find any answers? I'm getting this from the Facebook API. On a certain call, when you send some invalid data it returns a dictionary telling you what was wrong and why. Otherwise it returns an empty json array `[]`. So annoying. Ideas? – xan Dec 31 '14 at 15:16
  • @evanmcdonnal: Care to elaborate on these hacks? I'm hitting the same issue with the facebook api and I'm out of ideas! – xan Dec 31 '14 at 16:03

2 Answers2

4

I worked around a similar issue myself in the following way. I had tried using custom deserializers (since I was deserializing to a complex object) but in the end the following was much simpler, as it only applied to one of the many kinds of requests I was making.

request.OnBeforeDeserialization = (x =>
{
    x.Content = x.Content.Replace("[]", "{}");
});

Where I was constructing the request object for this particular request, I used the OnBeforeDeserialization property to set a callback which replaces the incorrect [] with {}. This works for me because I know the data I'm getting back in the rest of x.Content will never contain [] except in this specialized case, even in the values.

This might help someone else, but should definitely be used with care.

xan
  • 7,440
  • 8
  • 43
  • 65
  • Thanks xan! my code is [slightly different](https://gist.github.com/koreus7/b1be123762aea29b6362) but I just tested it with RestSharp 105.0.1.0 and it worked. Im a little surprised RestSharp doesn't handle it though. Do you think its worth reporting on GitGub? – koreus737 Sep 04 '15 at 13:09
  • I like the addition of `OnBeforeDeserialization` as it means I only have to do this once for all my requests in my request factory. This error drove me nuts for more than a day - turned out we simply hadn't hit the situation where our request returned no results in the array so we hadn't seen the error before. It does feel a *bit* hacky and dirty but there seemed to be no other better way to handle this and we didn't want to have to swap out the deserializer. – Steve Pettifer Sep 12 '17 at 10:02
0

I've never needed the client.AddHandler line, so I'm not sure you need that. Try this for your Execute method, though:

public T Execute<T>(RestRequest request) where T : class, new()
{
    RestClient client = new RestClient(baseUrl);
    client.AddHandler("text/plain", new JsonDeserializer());

    try
    {
        var response = client.Execute<T>(request);
        return response.Data;
    }
    catch (Exception ex)
    {
        // This is ugly, but if you don't want to bury any errors except when trying to deserialize an empty array to a dictionary...
        if (ex is InvalidCastException && typeof(T) == typeof(Dictionary<string, MyObject>))
        {
            // Log the exception?
            return new T();
        }

        throw;
    }
}
jfren484
  • 960
  • 10
  • 13
  • Not sure this helps answer the questions - yes it's possibly a nice fallback to prevent the exception propagating, but the trouble is the API being inconstant. Any thoughts on how to configure RestSharp to deal with this, or how to manually work around this? – xan Dec 31 '14 at 15:23
  • @xan - I edited my answer slightly. This answer IS a way to manually work around the problem the OP presented. I think the problem is a bug/deficiency in RestSharp and don't know of a way to configure RestSharp to handle it. – jfren484 Jan 29 '15 at 18:31