在Web Api方法中反序列化JSON对象列表

时间:2013-04-05 18:47:44

标签: json serialization asp.net-mvc-4 asp.net-web-api

我正在尝试研究如何从WEBAPI调用中的JSON请求中提取对象列表。在该对象列表中是Dictionary对象,List对象和List>对象

我的MVC控制器的请求看起来有点像这样:

//Gets a list of various objects
List<object> values = new List<object>(); 
values.add(GetItem1()); //Returns a Dictionary<string, string> object
values.add(GetItem2()); //Returns a List<string> object
values.add(GetItem3()); //List<KeyValuePair<string, string>> 

var content = new StringContent(JsonConvert.SerializeObject(values), Encoding.UTF8, "application/json");
HttpResponseMessage postResult = client.PostAsync(baseURL, content).Result;

在WEBAPI对象中,我有这个函数正在接收来自MVC控制器的调用。这是我遇到麻烦的地方,我无法从列表中获取数据。列表中的第一项恰好是字典。

[HttpPost]
public void LogError(List<object> myObjectList)
{
    Dictionary<string, string> items = (Dictionary<string, string>)myObjectList[0];
    List<string> moreItems = (List<string>)myObjectList[1];
    List<KeyValuePair<string, string>> evenMoreItems = (List<KeyValuePair<string, string>>)myObjectList[2];
}

如果我尝试开始使用该对象,我会收到错误:

Cannot cast 'myObjectList[0]' (which has an actual type of 'Newtonsoft.Json.Linq.JObject') to 'System.Collections.Generic.Dictionary<string,string>'

不幸的是,我完全不知道下一步该做什么。我似乎无法找到一种方法将List反序列化为这些单独的对象类型。

2 个答案:

答案 0 :(得分:2)

您遇到强制转换异常的原因是因为客户端和服务器丢失了类型信息。

让您的方案发挥作用的一种方法是执行以下操作

  1. 使用ObjectContent而不是StringContent,所以我们让格式化程序(即JsonMediaTypeFormatter)来处理序列化和反序列化
  2. 在客户端和服务器上启用TypeNameHandling,以便在线路上发送类型信息
  3. 服务器(WebApiConfig.cs):

     config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
    

    客户端:

            //Gets a list of various objects
            List<object> values = new List<object>();
            values.Add(GetItem1()); //Returns a Dictionary<string, string> object
            values.Add(GetItem2()); //Returns a List<string> object
            values.Add(GetItem3()); //List<KeyValuePair<string, string>> 
    
            var formatter = new JsonMediaTypeFormatter();
            formatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
    
            var content = new ObjectContent<List<object>>(values, formatter);
            HttpResponseMessage postResult = client.PostAsync(baseURL, content).Result;
    

    示例请求正文:

      

    { “$类型”:“System.Collections.Generic.List 1[[System.Object, mscorlib]], mscorlib","$values":[{"$type":"System.Collections.Generic.Dictionary -2 - [[System.String,   mscorlib],[System.String,mscorlib]],   mscorlib程序 “ ”DictionaryKey1“: ”DictionaryValue1“},{ ”$类型“:” System.Collections.Generic.List 1[[System.String, mscorlib]], mscorlib","$values":["ListItem1"]},{"$type":"System.Collections.Generic.List 1 [[System.Collections.Generic.KeyValuePair`2 [[System.String,   mscorlib],[System.String,mscorlib]],mscorlib]],   mscorlib程序”, “$值”:[{ “密钥”: “KeyValuePairKey”, “值”: “KeyValuePairKeyValue”}]}]}

答案 1 :(得分:0)

我可能错了,但是我无法接受

列表[对象]

如何知道这种类型是什么?您需要指定要进入的类型的具体对象吗?

从简单的事情开始:

public class TestClass
{
    public int Id { get; set; }
    public string Name { get; set; }
}

List values = new List();     values.Add(new TestClass(){Id = 1,Name =“test1”});     values.Add(new TestClass(){Id = 12,Name =“test2”});

var content = new StringContent(JsonConvert.SerializeObject(values), Encoding.UTF8, "application/json");
HttpResponseMessage postResult = client.PostAsync(baseURL, content).Result;

接收webapi方法:

public void LogError(List<TestObject> myObjectList)
{ // breakpoint here and see what myObjectList contains

}