【问题标题】:Gracefully handling an empty json object in RestSharp在 RestSharp 中优雅地处理一个空的 json 对象
【发布时间】:2012-07-16 23:13:16
【问题描述】:

我有以下代码:

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]”。

有没有办法优雅地处理这个问题?

【问题讨论】:

  • 你有机会改变服务器的响应吗?它应该返回一个空对象 {} 而不是空数组 []。即使在 JSON 中,两者也不兼容。
  • 我能想到一些简单的技巧,但仅此而已。
  • @Thomas:有人对此有更多想法吗?找到任何答案?我从 Facebook API 得到这个。在某个调用中,当您发送一些无效数据时,它会返回一个字典,告诉您出了什么问题以及原因。否则返回一个空的 json 数组 []。很烦人。想法?
  • @evanmcdonnal:想详细说明这些技巧吗?我在使用 facebook api 时遇到了同样的问题,但我没有想法!

标签: c# .net restsharp


【解决方案1】:

我自己通过以下方式解决了类似的问题。我曾尝试使用自定义反序列化器(因为我要反序列化为一个复杂的对象),但最后下面的内容要简单得多,因为它只适用于我提出的多种请求中的一种。

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

在我为这个特定请求构造请求对象的地方,我使用了OnBeforeDeserialization 属性来设置一个回调,用{} 替换不正确的[]。这对我有用,因为我知道我在 x.Content 的其余部分返回的数据将永远不会包含 [],除非在这种特殊情况下,即使在值中也是如此。

这可能对其他人有帮助,但绝对应该小心使用。

【讨论】:

  • 谢谢 xan!我的代码是slightly different,但我刚刚用 RestSharp 105.0.1.0 对其进行了测试,它工作正常。我有点惊讶 RestSharp 没有处理它。你认为它值得在 GitGub 上报道吗?
  • 我喜欢添加OnBeforeDeserialization,因为这意味着我只需为我的请求工厂中的所有请求执行一次。这个错误让我疯了一天多——结果我们根本没有遇到我们的请求在数组中没有返回结果的情况,所以我们之前没有看到这个错误。它确实感觉有点有点 hacky和肮脏,但似乎没有其他更好的方法来处理这个问题,我们不想换掉反序列化器。
【解决方案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;
    }
}

【讨论】:

  • 不确定这是否有助于回答问题 - 是的,这可能是防止异常传播的一个很好的后备方案,但问题是 API 不稳定。关于如何配置 RestSharp 来处理此问题或如何手动解决此问题的任何想法?
  • @xan - 我稍微编辑了我的答案。这个答案是一种手动解决 OP 提出的问题的方法。我认为问题是 RestSharp 中的错误/缺陷,并且不知道如何配置 RestSharp 来处理它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多