RestSharp 和 OData - 问题反序列化 JSON

RestSharp and OData - Issue Deserializing JSON

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

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

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,\"active\":false}]}"

然而 resultdata 并没有真正获取数据...它初始化了对象但是 ID,enabled 和 active 都是 0,false,false。

我们对此相当陌生...不过我的感觉是,由于返回的响应不是 100%,json 数据可能是问题所在?

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

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

你是对的:从 OData 资源端点取回集合时,实际记录并未表示为 top-level 数组。要以您的示例为基础,您将返回:

{
   "@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 或 what-have-you,任何保证 return 零或一个结果而不是数组的资源,则没有必要这样做).

你应该使用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();