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();
我和我的团队正在使用 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();