在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数

Posted

技术标签:

【中文标题】在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数【英文标题】:No parameterless constructor defined for type of 'System.String' during JSON deserialization 【发布时间】:2012-03-12 07:35:46 【问题描述】:

这看起来应该很容易,但是当我尝试将deserialize 一些简单的 JSON 转换为托管类型时,我遇到了异常。例外是:

MissingMethodException 没有为“System.String”类型定义无参数构造函数

虽然 System.String 确实没有无参数构造函数,但我不清楚为什么这很重要。

执行反序列化的代码是:

using System.Web.Script.Serialization;
private static javascriptSerializer serializer = new JavaScriptSerializer();
public static MyType Deserialize(string json)

    return serializer.Deserialize<MyType>(json);

我的类型大致是:

public class MyType

    public string id  get; set; 
    public string type  get; set; 
    public List<Double> location  get; set; 
    public Address address  get; set; 
    public Dictionary<string, string> localizedStrings  get; set; 

另一个类是一个地址:

public class Address

    public string addressLine  get; set; 
    public string suite  get; set; 
    public string locality  get; set; 
    public string subdivisionCode  get; set; 
    public string postalCode  get; set; 
    public string countryRegionCode  get; set; 
    public string countryRegion  get; set; 

这是 JSON:


    "id": "uniqueString",
    "type": "Foo",
    "location": [
        47.6,
        -122.3321
    ]
    "address": 
        "addressLine": "1000 Fourth Ave",
        "suite": "en-us",
        "locality": "Seattle",
        "subdivisionCode": "WA",
        "postalCode": "98104",
        "countryRegionCode": "US",
        "countryRegion": "United States"
    ,
    "localizedStrings": 
        "en-us": "Library",
        "en-ES": "La Biblioteca"
    

即使我的 JSON 只是:


    "id": "uniquestring"

谁能告诉我为什么 System.String 需要无参数构造函数?

【问题讨论】:

MissingMethodExceptionstring 类型相关联(没有无参数构造函数),而不是与 JavaScriptSerializer 相关联。 可能重复:***.com/questions/2959605 DataContractJsonSerializer 通常是比JavaScriptSerializer 更好的选择。 谢谢罗伯特,我看到 System.String 没有无参数构造函数;我只是不清楚为什么这很重要。 谢谢史蒂夫。我无法为这个项目选择反序列化类。 【参考方案1】:

无参数构造函数需要任何类型的反序列化。想象一下,您正在实现一个反序列化器。您需要:

    从输入流中获取对象类型(在本例中为字符串) 实例化对象。 如果没有默认构造函数,你就无法做到这一点。 从流中读取属性/值 将流中的值分配给在步骤 2 中创建的对象。

【讨论】:

哦,但是there is a way :) @LucasTrzesniewski 你能把这个作为答案发布吗? @jrh 我上面的评论指的是 "You have no way to do that if there is no default constructor" 这个答案的一部分,但它不能解决 OP有任何问题。 @LucasTrzesniewski 是的,我明白你的意思,现在我更仔细地查看它,它不适用于字符串。这是很好的信息。对于字符串它没有用,但对于尝试反序列化任意对象的更一般的情况,它绝对有用。 如果 Lucas 的链接中断(MSDN 喜欢移动 URL)... 使用 FormatterServices.GetUninitializedObject 来解决没有默认构造函数的问题。来自页面的引用:“因为对象的新实例被初始化为零并且没有运行构造函数,所以该对象可能不代表该对象认为有效的状态。应该只使用当前方法当用户打算立即填充所有字段时进行反序列化。它不会创建未初始化的字符串,因为创建不可变类型的空实例没有任何意义。"【参考方案2】:

我遇到了同样的问题,这就是解决问题的原因。

干杯!

//Deserializing Json object from string
DataContractJsonSerializer jsonObjectPersonInfo = 
    new DataContractJsonSerializer(typeof(PersonModel));
MemoryStream stream = 
    new MemoryStream(Encoding.UTF8.GetBytes(userInfo));
PersonModel personInfoModel = 
    (PersonModel)jsonObjectPersonInfo.ReadObject(stream);

【讨论】:

【参考方案3】:

如果我自己需要它,可以复活它;在我的情况下,错误出现在 JSON 中。

我正在反序列化为 List&lt;string&gt;,但 JSON 错误地传递了一个 ey 值对列表,例如


    "Roles": [ 
         "ID": "Administrator", "Name": "Administrator" , 
         "ID": "Client", "Name": "Client" 
    ]

进入:

public List<string> Roles  get; set; 

当它试图将对象反序列化为字符串时,这会导致 OP 出错。

如果给出失败的属性名称会很方便!

【讨论】:

以上是关于在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数的主要内容,如果未能解决你的问题,请参考以下文章

在反序列化期间将 JSON 日期转换为 .NET DateTime 的正确方法

在使用 Jackson 反序列化期间选择性地忽略 JSON 属性

在JSON反序列化期间抛出自定义错误

在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性

反序列化期间的 JSON.Net Ignore Property

在JMS Serializer上反序列化期间构造对象