【问题标题】:Deserialize Dictionary with JSON.NET使用 JSON.NET 反序列化字典
【发布时间】:2012-05-14 14:38:31
【问题描述】:

我正在使用 Newtonsoft.Json 版本 4.0.8 并尝试将它与 Web API 一起使用。 所以我想用

反序列化JSON
JsonConvert.DeserializeObject<AClass>(jsonString);

这一直有效,直到我将 Dictionary 作为属性添加到此类并想要反序列化它。

json字符串格式为

{ 
   "Date":null,
   "AString":"message",
   "Attributes":[
                   {"Key":"key1","Value":"value1"},      
                   {"Key":"key2","Value":"value2"}
                ],
    "Id":0,
    "Description":"...
}

当反序列化 JsonSerializationException 类型的异常时出现消息:“无法将 JSON 数组反序列化为类型 'System.Collections.Generic.Dictionary`2[System.String,System.String]'。

我在这里做错了什么?

更新1: 当使用 JSON.NET 进行序列化时,我得到以下字典:

Attributes":{"key1":"value1","key2":"value2"}

似乎 WebApi 以不同于 Json.Net 的方式反序列化对象。 服务器端我使用以下行进行隐式反序列化:

return new HttpResponseMessage<AClass>(object);

更新 2: 作为一种解决方法,我现在来到以下线路服务器端。

return new HttpResponseMessage<string>(JsonConvert.SerializeObject(license).Base64Encode());

我用 Json.Net 服务器端将其转换为 base64 编码字符串。所以Json.Net可以反序列化自己的格式。

但它仍然不是我想要的,所以他们有什么进一步的建议吗?

【问题讨论】:

  • 序列化类会得到什么JSON?
  • 感谢您的快速回复。我相应地更新了我的问题。
  • 除非 Web API 或 Newtonsoft 上有一个选项可以让它以“相反”的方式处理字典,否则我建议在每一端使用相同的库(序列化/反序列化),如果在一切皆有可能。

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


【解决方案1】:

如果您将Attributes 声明为List&lt;KeyValuePair&lt;string, string&gt;&gt;,它应该可以工作

【讨论】:

    【解决方案2】:

    来自this post,来电

    JsonConvert.SerializeObject(yourObject, new KeyValuePairConverter());
    

    以 Web API 为您创建的格式获取 JSON。

    因此,人们可能会认为调用

    JsonConvert.DeserializeObject<AClass>(jsonString, new KeyValuePairConverter());
    

    将执行相反的操作并正确处理 Web API 的样式。

    不过,我不知道这种重载是否存在;试一试,看看会发生什么......

    【讨论】:

    • 我试过但结果相同。即使在反序列化时应用了 keyvaluepairconverter 也会发生相同的异常..
    • 嗯,很公平。值得一试。
    【解决方案3】:
    Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(strJsonResult);
    

    【讨论】:

      【解决方案4】:

      如果是 .NET 4,您可以使用 DataContract 属性和 DataContractJsonSerializer Class 来强制执行消息格式:

          [DataContract]
          public class Message
          {
              [DataMember]
              public DateTime? Date { get; set; }
              [DataMember]
              public string AString { get; set; }
              [DataMember]
              public Dictionary<string, string> Attributes { get; set; }
              [DataMember]
              public int Id { get; set; }
              [DataMember]
              public string Description { get; set; }
          }
      
              DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Message));
      
              Message message = null;
              using (MemoryStream jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
              {
                  // Deserialize
                  message = (Message)jsonSerializer.ReadObject(jsonStream);
      
                  // Go to the beginning and discard the current stream contents.
                  jsonStream.Seek(0, SeekOrigin.Begin);
                  jsonStream.SetLength(0);
      
                  // Serialize
                  jsonSerializer.WriteObject(jsonStream, message);
                  jsonString = Encoding.UTF8.GetString(jsonStream.ToArray());
              }
      

      对此进行序列化会产生以下 JSON:

      {"AString":"message","Attributes":[{"Key":"key1","Value":"value1"},{"Key":"key2","Value":"value2"}],"Date":null,"Description":"...","Id":0}
      

      【讨论】:

      • 谢谢,但我想用 Json.Net 来做,因为我们已经在解决方案的几个地方使用它,所以我真的不想再使用 .Nets DataContractSerializer。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      相关资源
      最近更新 更多