如何解决KeyNotFoundException问题

4

我正在使用以下代码将JSON字符串反序列化为自己的类:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> x = (Dictionary<string, object>)serializer.DeserializeObject(json);
MyJsonStruct data = serializer.Deserialize<MyJsonStruct>(x["d"].ToString());

但是一旦调用JavaScriptSerializer.Deserialize()方法,就会抛出异常:

A first chance exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in mscorlib.dll
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)

有没有办法找出触发异常的关键是哪个?希望能提供一种通用的技术(或方法)来解决这种类型的异常。 更新: 如果我删除[d],会收到以下消息:
A first chance exception of type 'System.ArgumentException' occurred in System.Web.Extensions.dll
System.ArgumentException: Invalid JSON primitive: System.Collections.Generic.Dictionary.
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)

但是,我正在寻找一种通用技术,而不仅仅是解决这个特定的实例。

2个回答

5
在Deserialize语句上打一个断点,然后使用即时窗口键入x["d"].ToString()。这将告诉您它的求值结果,这将等同于您尝试反序列化的键。
如果在评估过程中出现错误,则您的x字典没有“d”作为键,这是您可以检查的另一件事。
编辑:我不认为Daniel建议您完全删除["d"]。如果您这样做,您正在向Deserialize传递一个字典,而它显然期望一个字符串。这种类型不匹配会导致您看到的新错误。相反,Daniel建议您的字典不包括"d"作为有效键。这可能是或可能不是,我不确定。

非常好的提示,谢谢!我会尝试一下。同时,请查看我的更新在原帖中。 - Not So Sharp
谢谢。当我设置断点并按照您的建议操作时,对于*x["d"].ToString()*,我得到了值为'x["d"]' threw an exception of type 'System.Collections.Generic.KeyNotFoundException'的异常。因此,看起来它是问题的源头,但是如果字典没有d作为第一个(也是唯一的)键,我该如何处理呢? - Not So Sharp
2
@NotSoSharp 字典不需要将“d”作为键。我建议您在Visual Studio中将变量“x”放在监视下,这样您就可以随意展开它并查看它。特别是您可能要检查“.Count”属性。如果它为0,则根本没有任何键。 - tmesser
2
成功了!原来 .ToString() 完全是误导性的(这就是当我试图从 一个例子 中学习时发生的事情)。同时,Dictionary<string, object> x = (Dictionary<string, object>)serializer.DeserializeObject(json); 语句也完全没有必要:我只需要将原始的 json 字符串传递给 Deserialize() 即可。我应该知道得更好。非常感谢。 - Not So Sharp

1
很可能是在你的x中访问d的值。

通过使用 d,我只是遵循 .NET 3.5+ 将 'D' 添加到结果 的提示。如果我将其删除,则会得到更多的 Invalid JSON primitive 异常,这更加令人恐慌。 - Not So Sharp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接