2014-05-10 71 views
12

我想在我的mvc项目中使用ReadAsAsync().net 4.0。结果为空。使用ReadAsAsync <T>()反序列化复杂的Json对象

如果我进入URI地址栏,结果在铬作为(标签名称更改):

<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的属性为空或默认值。类定义如下。我想将内容作为对象阅读,但我不能。你有什么建议来解决这个问题?我究竟做错了什么?提前致谢。

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; } 
} 

回答

7

我定义了一个新的类为:

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

然后我用这个包装带,

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

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

6

阅读您的解决方案后,我想出了一个并不需要一个额外的类:

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; 
    } 
+1

你甚至可以进一步简化这个'output = await response.Content.ReadAsAsync ();' – Nkosi

3

对于未来的读者着想,我认为正确的做法是使用ReadAsAsync重载需要​​,并提供一个具有与服务器上序列化相同的设置的格式化程序。这应该解决它。

0

可以直接在客户端ReadAsAsync和MyListResponse中使用(因此无需ResponseWrapper)。为此,您可以在“apiuri”的操作合同中定义“BodyStyle = WebMessageBodyStyle.Bare”,而不是“BodyStyle = WebMessageBodyStyle.Wrapped”(服务器端,即服务合同)。