Изящно обрабатывая пустой объект json в RestSharp

У меня есть следующий код:

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;
}

Проблема заключается в том, что иногда ответом будет пустой массив json []. И когда я запускаю этот код, я получаю следующее исключение: Невозможно наложить объект типа "RestSharp.JsonArray" на тип "System.Collections.Generic.IDictionary`2 [System.String, System.Object]".

Есть ли способ изящно справиться с этим?

Ответ 1

Я сам работал над подобной проблемой следующим образом. Я попытался использовать пользовательские десериализаторы (так как я десериализовался на сложный объект), но в итоге следующее было намного проще, поскольку оно применимо только к одному из многих видов запросов, которые я делал.

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

Когда я создавал объект запроса для этого конкретного запроса, я использовал свойство OnBeforeDeserialization для установки обратного вызова, который заменяет неправильный [] на {}. Это работает для меня, потому что я знаю, что данные, которые я возвращаю в оставшуюся часть x.Content, никогда не будут содержать [], кроме этого специализированного случая, даже в значениях.

Это может помочь кому-то другому, но обязательно следует использовать с осторожностью.

Ответ 2

Мне никогда не нужна линия client.AddHandler, поэтому я не уверен, что вам это нужно. Попробуйте это для своего метода Execute:

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;
    }
}