1

我正在尝试研究如何从 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 反序列化为这些单独对象类型的方法。

4

2 回答 2

2

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

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

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

服务器(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;

样品请求正文:

{"$type":"System.Collections.Generic.List 1[[System.Object, mscorlib]], mscorlib","$values":[{"$type":"System.Collections.Generic.Dictionary2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib","DictionaryKey1":"DictionaryValue1"},{"$type" :"System.Collections.Generic.List 1[[System.String, mscorlib]], mscorlib","$values":["ListItem1"]},{"$type":"System.Collections.Generic.List1[[System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib]], mscorlib","$values" :[{"Key":"KeyValuePairKey","Value":"KeyValuePairKeyValue"}]}]}

于 2013-04-06T19:20:01.120 回答
0

我可能是错的,但在我脑海中你不能有一个

列表[对象]

因为它将如何知道类型是什么?您需要指定传入类型的具体对象吗?

从简单的事情开始:

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

列表值 = 新列表();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

}
于 2013-04-05T18:49:55.860 回答