【问题标题】:Unable to deserialize JSON to a Dictionary<string, List<string>> using JavaScriptSerializer无法使用 JavaScriptSerializer 将 JSON 反序列化为 Dictionary<string, List<string>>
【发布时间】:2015-11-12 18:06:47
【问题描述】:

我在使用 JavaScriptSerializer 库的 c# 代码中反序列化 JSON 时遇到问题。

这是我的 JSON 示例:

{"A":["a","b","c","d"],"B":["a"],"C":[]}

我正在使用字典来保存 JSON,如下所示:

Dictionary<string, List<string>> myObject;

这就是我解析 JSON 并将其转换为我的对象的方式:

myObject= (Dictionary<string, List<string>>)jsc.DeserializeObject(json);

但是,在运行时,上一行抛出如下 Casting 异常

无法转换类型的对象 System.Collections.Generic.Dictionary2[System.String,System.Object] 输入 System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[System.String]]

由于某种原因,JavaScriptSerializer 无法识别具有字符串为 List&lt;string&gt; 的 JSON 数组

更新

我用一些硬编码字符串填充了我的Dictionary 数据结构,以查看什么是序列化版本。事实证明这正是我输入的 JSON 字符串。

【问题讨论】:

  • 如果您使用 var 定义 myObject 而不是显式地定义为 Dictionary 会发生什么?
  • @Necoras 那也没用 :(
  • @sjokkogutten 有正确的答案,但错误消息确实告诉您为什么抛出异常,DeserializeObject 方法返回 Dictionary&lt;string,object&gt;,然后您尝试将其转换为 @ 987654328@。即使您要关闭的泛型类型可以强制转换,但这并不意味着泛型类型本身可以。例如,您不能将IEnumerable&lt;string&gt; 转换为IEnumerable&lt;object&gt;,即使字符串确实从对象继承。泛型不是那样工作的。

标签: c# .net json casting javascriptserializer


【解决方案1】:

不使用DeserializeObject 方法,而是使用通用Deserialize&lt;T&gt; 方法并将Dictionary&lt;string, List&lt;string&gt;&gt; 指定为类型参数。然后它将正常工作:

string json = @"{""A"":[""a"",""b"",""c"",""d""],""B"":[""a""],""C"":[]}";

JavaScriptSerializer serializer = new JavaScriptSerializer();

Dictionary<string, List<string>> myObject = 
    serializer.Deserialize<Dictionary<string, List<string>>>(json);

foreach (KeyValuePair<string, List<string>> kvp in myObject)
{
    Console.WriteLine(kvp.Key + ": " + string.Join(",", kvp.Value));
}

输出:

A: a,b,c,d
B: a
C:

【讨论】:

  • 这行得通!谢谢!由于某种原因,我完全错过了这种方法。我认为这与 JavaScriptSerializer.Deserialize Method (String, Type) 相同。愚蠢的我。
  • 没问题;很乐意提供帮助。
【解决方案2】:

问题是转换为List&lt;string&gt; 如果可以接受强制转换为对象,您可以这样做:

string json = "{\"A\":[\"a\",\"b\",\"c\",\"d\"],\"B\":[\"a\"],\"C\":[]}";
var serializer = new JavaScriptSerializer();
var deserializedValues = (Dictionary<string, object>)serializer.Deserialize(json, typeof(object));

我还建议查看Json.NET,它在序列化/反序列化方面做得更好

【讨论】:

  • 您甚至可以使用通用的Deserialize 方法并指定与您要查找的类型相同的类型。这样您就不必在代码中进行任何转换。
【解决方案3】:

根据 JSON 结构创建一个 Type,然后像这样在 Serialization 或 DeSerialization 中使用 Type。

我使用 Web Essentials Visual Studio 扩展中的功能从 JSON 创建 RootObject。

public class JSONSerializer
{
    public void RunIt()
    {
        string json = "{\"A\":[\"a\",\"b\",\"c\",\"d\"],\"B\":[\"a\"],\"C\":[]}";

        JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

        Rootobject jsonObject = serializer.Deserialize<Rootobject>(json);

        Console.Write(serializer.Serialize(jsonObject));
    }
}

public class Rootobject
{
    public string[] A { get; set; }
    public string[] B { get; set; }
    public object[] C { get; set; }
}

【讨论】:

  • 我不能直接使用这个方法。我不知道 RootObject 中将出现的键/数组对的数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多