【问题标题】:JSON deserialize to List<T>JSON 反序列化为 List<T>
【发布时间】:2014-03-26 21:12:23
【问题描述】:

我有一个 ASP.NET Web API GET 端点

public class MyType
{
  public bool Active { get; set; }
  public DateTime CreateDate { get; set; }
  public int Id { get; set; }
  public string Description { get; set; }
}

public class MyResponse
{
  public List<MyType> Results { get; set; }
}

[HttpGet]
public MyResponse GetResults()

对于Results包含2个项目的情况,json返回字符串为

{"Results":[{"Active":true,"CreateDate":"2014-01-01T00:00:00","Id":1,"Description":"item 1 description"},{"Active":true,"CreateDate":"2014-01-01T00:00:00","Id":2,"Description":"item 2 description"}]}

在客户端,我希望将 json 反序列化为 List&lt;MyType&gt;

(以简洁的名义用语言有点松散)

List<MyType> results = HttpResponseMessage.Content.ReadAsAsync<List<MyType>>(new [] { new JsonMediaTypeFormatter () }).Result;

但这会引发异常

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[MyType]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClass8.<ReadFromStreamAsync>b__6()
   at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)

【问题讨论】:

  • 详细错误信息的哪一部分你不明白?对象不是数组。
  • json长什么样子,MyType类的属性是什么?
  • 感谢@BateTech 的回复,我用附加信息修改了我的帖子。

标签: c# json web-services asp.net-web-api deserialization


【解决方案1】:

您的 Web API 方法返回一个对象,而不是一个列表 - 而您正试图强制反序列化器将其重构为一个列表 - 这是行不通的。

您需要:

  1. 在您的GetResults() 方法中返回列表本身(即将其从MyResponse 更改为List&lt;MyType&gt;,或者
  2. 在客户端,将接收到的数据转换为类型MyResponse,而不是List&lt;MyType&gt;

【讨论】:

  • 但是在 MyResponse.Results 包含多个项目的情况下,服务器返回的原始 json 包含多个对象(逗号分隔)。
【解决方案2】:

MyResponse 类将被序列化为 JSON,因此在调用 ReadAsAsync 方法时应使用该类型。

MyResponse responseContent = HttpResponseMessage.Content.ReadAsAsync<MyResponse>(new [] { new JsonMediaTypeFormatter () });

那么如果你想访问结果列表,那么使用responseContent.Results

从我看到的示例中,您也可以省略IEnumerable&lt;MediaTypeFormatter&gt; 参数,这样也可以正常工作。 http://msdn.microsoft.com/en-us/library/hh944541(v=vs.118).aspx

MyResponse responseContent = HttpResponseMessage.Content.ReadAsAsync<MyResponse>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2021-02-13
    相关资源
    最近更新 更多