反序列化错误:值不能为空。参数名称:类型

Posted

技术标签:

【中文标题】反序列化错误:值不能为空。参数名称:类型【英文标题】:Deserialization error: value cannot be null. Parameter name: type 【发布时间】:2011-12-20 16:56:59 【问题描述】:

我正在尝试反序列化一个 json 响应并且得到 value cannot be null 错误。

非常感谢任何帮助!我以这种方式反序列化了许多其他 json 字符串,并且从未遇到过这个错误。我不确定是什么原因造成的。谢谢!

这是对象的代码:

[Serializable]
public class LocationResponse

    public string authenticationResultCode  get; set; 
    public string brandLogoUri  get; set; 
    public string copyright  get; set; 
    public List<ResourceSet> resourceSets  get; set; 
    public int statusCode  get; set; 
    public string statusDescription  get; set; 
    public string traceId  get; set; 


[Serializable]
public class ResourceSet

    public int estimatedTotal  get; set; 
    public List<Resource> resources  get; set; 


[Serializable]
public class Resource

    //public string __type  get; set; 
    //public List<double> bbox  get; set; 
    public string name  get; set; 
    public Point point  get; set; 
    //public Address address  get; set; 
    //public string confidence  get; set; 
    //public string entityType  get; set; 


[Serializable]
public class Point

    public string type  get; set; 
    public List<double> coordinates  get; set; 


[Serializable]
public class Address

    public string countryRegion  get; set; 
    public string formattedAddress  get; set; 

要反序列化的代码:

System.Web.Script.Serialization.javascriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = "\"authenticationResultCode\":\"ValidCredentials\",\"brandLogoUri\":\"http:\\/\\/dev.virtualearth.net\\/Branding\\/logo_powered_by.png\",\"copyright\":\"Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.\",\"resourceSets\":[\"estimatedTotal\":1,\"resources\":[\"__type\":\"Location:http:\\/\\/schemas.microsoft.com\\/search\\/local\\/ws\\/rest\\/v1\",\"bbox\":[33.177484847720336,35.531577579036423,33.235425613705445,35.623878963932327],\"name\":\"Qiryat Shemona, Israel\",\"point\":\"type\":\"Point\",\"coordinates\":[33.206455230712891,35.577728271484375],\"address\":\"adminDistrict\":\"Northern\",\"countryRegion\":\"Israel\",\"formattedAddress\":\"Qiryat Shemona, Israel\",\"locality\":\"Qiryat Shemona\",\"confidence\":\"High\",\"entityType\":\"PopulatedPlace\"]],\"statusCode\":200,\"statusDescription\":\"OK\",\"traceId\":\"NVM001351\"";
LocationResponse response = ser.Deserialize<LocationResponse>(json);

我收到一个错误,我无法弄清楚代码或 json 的哪一部分给出了这个错误:异常详细信息:System.ArgumentNullException:值不能为空。 参数名称:类型

如果有帮助,这里是堆栈跟踪:

[ArgumentNullException: Value cannot be null.
Parameter name: type]
System.Activator.CreateInstance(Type type, Boolean nonPublic) +7468694
System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject) +406
System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject) +71
System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject) +147
System.Web.Script.Serialization.ObjectConverter.ConvertObjectToType(Object o, Type type, JavaScriptSerializer serializer) +21
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +181
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeList(Int32 depth) +119
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +210
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) +422
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +147
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeList(Int32 depth) +119
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +210
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) +422
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +147
System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer) +51
System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +37
System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(String input) +70

【问题讨论】:

【参考方案1】:

问题在于 JSON 中的 __type 字段。

阅读以下内容的答案:Problem with deserializing JSON on datamember “__type” 似乎引用了:the "__type" field has a special meaning for DataContractJsonSerializer, denoting the type to which the object should be deserialized.

从 JSON 中删除 __type 解决了该问题。

一个选项,(如果您无法控制 JSON),我刚刚使用 JSON.NET 库对此进行了测试,它按预期工作,反序列化没有错误。

LocationResponse response = JsonConvert.DeserializeObject<LocationResponse>(json);

【讨论】:

太棒了!花了很多时间在网上冲浪来找到这个解决方案【参考方案2】:

这已经很晚了,但我遇到了同样的问题,并通过向相关类添加默认构造函数并确保该类的属性的设置器是公共的来解决它。这解决了我的问题(FastJson 和 JSON.net 都存在)。

以防万一有人遇到问题,而上面的答案对他们没有帮助。

【讨论】:

我只是想知道同样的事情,并阅读了您的内容并立即尝试了。这也解决了我的问题!【参考方案3】:
    从堆栈跟踪中可以看到,System.Activator.CreateInstance(Type type, bool) 方法引发了异常。 因为反序列化程序将 null 作为“类型”传递给我上面提到的方法,所以抛出它。

这很可能是因为反序列化程序无法找到将 JSON 反序列化为的正确类型。尝试先序列化 LocationResponse 类的实例,然后将结果与您尝试反序列化的字符串进行比较。

【讨论】:

以上是关于反序列化错误:值不能为空。参数名称:类型的主要内容,如果未能解决你的问题,请参考以下文章

使用变量名数组反序列化 JSON

Kotlin Model类在Json反序列化过程为空性探索

Objective-C Json反序列化(空值不能反序列化)

使用 XmlSerializer 将空 xml 属性值反序列化为可为空的 int 属性

反序列化错误 : 不能构造Dto的实例(尽管至少有一个Creator存在):不能从对象值反序列化。

没有参数名称的JSON4S反序列化