使用ReadAsAsync <t>()反序列化复杂的Json对象</t>

时间:2014-05-10 03:17:09

标签: asp.net-mvc-4 .net-4.0 httpclient

我想在我的mvc项目中使用ReadAsAsync()和.net 4.0。结果为null。

如果我输入uri到地址栏,则chrome的结果为(标签名称已更改):

<ns2:MyListResponse xmlns:ns2="blablabla">
  <customerSessionId>xxcustomerSessionIdxx</customerSessionId>
  <numberOfRecordsRequested>0</numberOfRecordsRequested>
  <moreResultsAvailable>false</moreResultsAvailable>
  <MyList size="1" activePropertyCount="1">
    <MySummary order="0">
      <id>1234</id>
      <name>...</name>
      .
      .   
    </MySummary>
  </MyList>
</ns2:MyListResponse>

如果我在代码中使用该语句:

using (var client = new HttpClient())
{
     var response = client.GetAsync(apiUri).Result;
     var message = response.Content.ReadAsStringAsync().Result;

     var result1 = JsonConvert.DeserializeObject<MyListResponse>(message);
     var result2 = response.Content.ReadAsAsync<MyListResponse>().Result;
}

消息以字符串格式显示为"{\"MyListResponse\":{\"customerSessionId\"...}",对应于json对象:

{"MyListResponse":
    {"customerSessionId":"xxcustomerSessionIdxx",
     "numberOfRecordsRequested":0,
     "moreResultsAvailable":false,
     "MyList":
        {"@size":"1",
         "@activePropertyCount":"1",
         "MySummary":
            {"@order":"0",
             "id":1234,
             "name":"...",
             .
             .
            }
        }
    }
 } 

并且result1和result2的属性显示为null或默认值。类定义如下。我想将内容作为对象阅读,但我不能。您有什么建议来解决这个问题?我究竟做错了什么?提前谢谢。

public class MySummary
{
    public int @Order { get; set; }
    public string Id { get; set; }
    public string Name { get; set; }
    .
    .
}

public class MyList
{
    public int @Size { get; set; }
    public int @ActivePropertyCount { get; set; }
    public MySummary MySummary{ get; set; }
}

public class MyListResponse
{
    public string CustomerSessionId { get; set; }
    public int NumberOfRecordsRequested { get; set; }
    public bool MoreResultsAvailable { get; set; }
    public MyList MyList { get; set; }
}

4 个答案:

答案 0 :(得分:8)

我将一个新类定义为:

public class ResponseWrapper
{
    public MyListResponse MyListResponse { get; set; }
}

然后我使用了这个包装器,

 var result1 = JsonConvert.DeserializeObject<ResponseWrapper>(message);
 var result2 = response.Content.ReadAsAsync<ResponseWrapper>().Result;

然后它奏效了。我只需要MySummary对象,但我应该编写更多类来使其工作。

答案 1 :(得分:7)

在阅读完解决方案后,我想出了一个不需要额外课程的课程:

    private static async Task<U> Execute<U>(HttpClient client, string path)
    {
        U output = default(U);

        HttpResponseMessage response = await client.GetAsync(path);

        if (response.IsSuccessStatusCode)
        {
            var jsonAsString = await response.Content.ReadAsStringAsync();
            output = JsonConvert.DeserializeObject<U>(jsonAsString);
        }
        else
        {
            throw new ApplicationException(string.Format("Response message is not OK. Issues in action: {0}", path));
        }

        return output;
    }

答案 2 :(得分:4)

为了将来的读者,我认为正确的方法是使用ReadAsAsync重载,它需要IEnumerable<MediaTypeFormatter>并提供一个格式化程序,其服务器上使用相同的设置进行序列化。那应该解决它。

答案 3 :(得分:0)

可以直接在客户端使用ReadAsAsync和MyListResponse(因此没有ResponseWrapper)。为此,您可以定义&#34; BodyStyle = WebMessageBodyStyle.Bare&#34;在&#34; apiuri&#34;的运营合同中而不是&#34; BodyStyle = WebMessageBodyStyle.Wrapped&#34; (服务器端,即服务合同)。