【问题标题】:No parameterless constructor defined for type of 'System.String' during JSON deserialization在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数
【发布时间】: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 相关联。
  • DataContractJsonSerializer 通常是比JavaScriptSerializer 更好的选择。
  • 谢谢罗伯特,我看到 System.String 没有无参数构造函数;我只是不清楚为什么这很重要。
  • 谢谢史蒂夫。我无法为这个项目选择反序列化类。

标签: c# json deserialization


【解决方案1】:

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

  1. 从输入流中获取对象类型(在本例中为字符串)
  2. 实例化对象。 如果没有默认构造函数,你就无法做到这一点
  3. 从流中读取属性/值
  4. 将流中的值分配给在步骤 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 出错。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      相关资源
      最近更新 更多