RestSharp 和 OData - 问题反序列化 JSON



我和我的团队正在与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;
}

在这个结果中,如果我们使用一个简单的类型,如人员(ID,启用,活动(,我们将在response.content中看到数据。

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

但是结果数据实际上并没有获取数据...它初始化对象,但 ID、启用和活动为 0、假、假。

我们对此相当陌生...我的感觉是,由于回复不是 100%,因此 JSON 数据可能是问题所在?

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

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

你是对的:从 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 不再原生使用 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 或您拥有的资源,任何保证返回零或一个结果而不是数组的内容(,则不需要这样做。

你应该使用响应。数据.价值

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(); 

最新更新