【问题标题】:Odata Controller: How to convert Odata response to C# object at clientOdata 控制器:如何在客户端将 Odata 响应转换为 C# 对象
【发布时间】:2019-03-25 22:17:51
【问题描述】:

我们收到如下 Odata 响应:

"{\r\n  \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"

现在说我们有一个类:

    public class myValidationResult
    {
        public myValidationResult()
        {
            Messages = new List<string>();
        }
        public List<string> Messages { get; set; }
        public bool IsValidEntity { get; set; }
    }

该类在MyOdataController类中使用如下:

public class MyODataController : ODataController 
{
        [Authorize(Roles = "Admin")]
        public async Task<IHttpActionResult> Post(T entity)
        {
                myValidationResult  vResult = new myValidationResult();
                vResult.Messages.Add("message 1");
                vResult.Messages.Add("message 2");
                vResult.Messages.Add("message 3");
                vResult.Messages.Add("message 4");
                vResult.IsValidEntity = false;

                 var strResult = JsonConvert.SerializeObject(vResult);
                var resp = Content(HttpStatusCode.BadRequest, strResult );

                return resp;
        }
}

为了客户端消费这个,我们在下面创建了类:

public class OData<T> 
{
    [JsonProperty("odata.context")]
    public string Metadata { get; set; }
    public T value { get; set; }
}

在我们调用 Odata 方法并将响应存储在 'msg' 的方法中:

var resp = msg.Result.Content.ReadAsStringAsync().Result;

resp 是:

"{\r\n  \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"


var odatares = JsonConvert.DeserializeObject<OData<myValidationResult>>(resp);

但上面的行给出错误:

Can not convert value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}  to <.....namespace......>myValidationResult

请相应地提出建议。

【问题讨论】:

  • 请修正你的格式,很难分辨出什么是什么。

标签: c# json.net odata


【解决方案1】:

OData 响应包含一个字符串,而不是 myValidationResult 的实例。此外,响应似乎缺少一些反斜杠。 (您确定显示的响应与您从服务中收到的完全一致吗?)

您可以在服务上修复myValidationResult 的序列化:

// Don't serialize vResult yourself. OData will do it for you.
var resp = Content(HttpStatusCode.BadRequest, vResult );

或者如下分两步反序列化。

var data = "{\r\n \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}";
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<string>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value);

还有一点:OData&lt;T&gt; 上的 JsonProperty 应该命名为 @odata.context

【讨论】:

  • 感谢回复:我最初已经尝试过对象 (vResult),但响应低于 & 无法在客户端获得预期结果:Id = 0x00000003,状态 = RanToCompletion,方法 =“{null}”,结果= "StatusCode: 401, ReasonPhrase: 'Unauthorized', 版本: 1.1, Content: System.Net.Http.StringContent, Headers:\r\n{\r\n Pragma: no-cache\r\n Cache-Control:无缓存\r\n 日期:2016 年 1 月 6 日,星期三 07:04:25 GMT\r\n 服务器:Microsoft-IIS/7.5\r\n X-AspNet-Version: 4.0.30319\r\n X-技术支持:ASP.NET\r\n 内容类型:application/json;odata.metadata=minimal\r\n 内容长度:97\r\n}"
  • 根据您的Authorize 方法的Authorize 属性,发出请求的用户似乎没有管理员角色。
【解决方案2】:

在我的情况下,OData 响应不包含字符串,而是包含数据字符串作为其第一个元素的对象数组。所以在这种情况下读取数据应该是这样的:

var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<object[]>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value[0].ToString());

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多