【问题标题】:RestSharp and OData - Issue Deserializing JSONRestSharp 和 OData - 反序列化 JSON 的问题
【发布时间】:2017-07-05 15:04:24
【问题描述】:

我和我的团队正在使用 OData 开展一个项目。我们正在尝试使用 RestSharp 客户端,但找不到在 C# 中将其与 OData 一起使用的最佳实践的任何干净示例。

我们遇到的问题是,在尝试获取数据时,我们认为它是 2 层 JSON。

private T execRequest<T>(RestClient client, RestRequest request, bool retry = true)
    {
        IRestResponse response;
        T resultdata = default(T);
        try
        {
            response = client.Execute(request);
        }
        catch (Exception)
        {
            throw;
        }
        if (response.StatusDescription == "OK") // TAKE CARE OF Session expired or invalid
        {
            resultdata = JsonConvert.DeserializeObject<T>(response.Content);
        }


       return resultdata;
    }

在这个结果中,如果我们使用像 Person (ID,enabled,active) 这样的简单类型,我们会在 response.content 中看到数据。

"{\"@odata.context\":\"http://localhost:56460/$metadata#Person\",\"value\":[{\"ID\":1090,\"enabled\":true, \"活动\":false}]}"

然而resultdata实际上并没有得到数据...它初始化了对象但是ID、启用和活动是0、假、假。

我们对此还很陌生……但我的感觉是,由于返回的响应不是 100%,json 数据可能是问题所在?

(p.s. 也在寻找一些与 OData 和 RESTSharp 相关的文档)。

edit:我们认为我们需要反序列化到更高级别的对象,因为 response.content 中的数据是一个对象,然后每个对象都是对象。我们正在尝试使用 OData 找到一个干净的示例,但还没有。

【问题讨论】:

  • 这是 实际 JSON 还是您在 VS 中看到的? “{\”不是有效的 JSON
  • 嗨,这是我们在 VS 中检查 response.content 时看到的内容
  • 在这种情况下T 是什么?
  • T 在这种情况下是人
  • 我们使用它来帮助我们解决问题...我不确定我应该回答自己的问题还是将其保留在 cmets 但是:stackoverflow.com/questions/26820275/…

标签: c# json odata restsharp


【解决方案1】:

您是对的:从 OData 资源端点检索集合时,实际记录不表示为顶级数组。以你的例子为基础,你回来了:

{
   "@odata.context":"http://localhost:56460/odata/$metadata#Person",
   "value": [
      {
        "ID": 1090,
        "enabled" : true,
        "active" : false
      },
      {
        // second Person object, and so on...
      }
   ]
}

实际包含您的结果的属性是value。您可以使用泛型创建一个简单的包装器来处理集合结果:

using System.Collections.Generic;

namespace Api.Models
{
    public class ODataCollectionWrapper<T> where T : class
    {
        public IEnumerable<T> Value { get; set; }
    }
}

现在当你使用 RestSharp 时,你可以在调用 Execute 方法时指定反序列化类型,并为自己节省一些代码。另请注意RestSharp no longer natively uses Json.NET(尽管您可以管理自己的反序列化并保留 Json.NET,如果您真的愿意)。

// RestSharp automatically deserializes to ODataCollectionWrapper<Person>
response = client.Execute<ODataCollectionWrapper<Person>>(request);

// Return the actual collection
return response.Value; // Contains IEnumerable<Person>

请注意,如果您只是检索单个资源(通过 ID 或你有什么,保证返回零或一个结果而不是数组的任何内容),则这不是必需的。

【讨论】:

    【解决方案2】:

    你应该使用 response.Data.Value

            var restRequest = new RestRequest($"Applications?$filter=Name eq '{applicationTargetName}'", Method.GET);
            var response = client.Execute<ODataCollectionWrapper<Application>>(restRequest);
    
            var application = response.Data.Value;
            return application.First(); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多