【问题标题】:How to deserialize (JSON) objects of a class type that implement an interface: error no parameterless constructor defined?如何反序列化(JSON)实现接口的类类型的对象:错误没有定义无参数构造函数?
【发布时间】:2013-10-18 01:19:35
【问题描述】:

使用 C#,.Net v4.0 - 给定以下结构:

public interface IInterface {...}

public class MyClass : IInterface 
{
   public MyClass() {}
   .
   .
   .
}

我确实在类中定义了无参数构造函数。

收到 JSON 对象后,我尝试反序列化 MyClass 并收到如下错误:

没有为此对象定义无参数构造函数

var serializer = new JavaScriptSerializer(new SimpleTypeResolver());
var newObject = serializer.Deserialize(jsonObject, myClass.GetType());

我也试过没有SimpletypeResolver()

我看到a few posts 似乎在我正在寻找的东西上徘徊,但并不完全在那里 - 除非我错过了什么。

MyClass 实现了接口,接口中不能定义默认构造函数。知道了。那么如何反序列化MyClass 对象呢?

【问题讨论】:

  • 向我们展示 MyClass 的代码。是否定义了无参数构造函数?

标签: c# json deserialization


【解决方案1】:

您需要告诉您的反序列化器想要将 json 转换为的具体类类型。一种方法是在 Json.Net 中实现 JsonConverter 类。

完整的人为工作示例。

public interface IMyClass
{
    void SetMyVariable(int value);
}

public class MyClass : IMyClass
{

    public int MyVariable;

    public MyClass()
    {
        MyVariable = 10;
    }

    public void SetMyVariable(int value)
    {
        this.MyVariable = value;
    }
}

public class MyParentClass
{
    public IMyClass IMyClass { get; set; }
}


public class MyClassConverter : JsonConverter
{
    /// <inheritdoc />
    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    /// <inheritdoc />
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader == null)
        {
            throw new ArgumentNullException("reader");
        }

        if (serializer == null)
        {
            throw new ArgumentNullException("serializer");
        }

        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        var jsonObject = JObject.Load(reader);
        var value = new MyClass();

        if (value == null)
        {
            throw new JsonSerializationException("No object created.");
        }

        serializer.Populate(jsonObject.CreateReader(), value);
        return value;
    }

    /// <inheritdoc />
    public override bool CanConvert(Type objectType)
    {
        return typeof(IMyClass).IsAssignableFrom(objectType);
    }
}

[TestClass]
public class UnitTest2
{
    [TestMethod]
    public void TestSerializer()
    {
        var myClass = new MyParentClass { IMyClass = new MyClass() };
        var serializedClass = JsonConvert.SerializeObject(myClass);
        var result = JsonConvert.DeserializeObject<MyParentClass>(serializedClass, new MyClassConverter());
        Assert.IsNotNull(result);
    }
}

【讨论】:

  • 我尝试了你的建议,但是当我使用 DeserializeObject&lt;MyClass&gt;... 时仍然遇到同样的错误 - 无法创建 IInterface 类型的实例。类型是接口或抽象类,不能实例化MyClassMyClass:IInterface
  • 更新了一个人为设计但在单元测试中有效的答案。
  • 我最终使用了这里建议的解决方案:stackoverflow.com/questions/19413475/…,创建了两个泛型类型,并删除了接口。这可能会在单元测试期间产生一些后果,但它确实有效。但是,我将您的答案标记为已接受,并且可能会在不久的将来重新访问它。谢谢。
【解决方案2】:

您可以使用Newtonsoft.Json 库来序列化/反序列化 .NET 对象 像这样:

var jsonString = JsonConvert.SerializeObject(myObject);
var jsonObject =  JsonConvert.DeserializeObject(jsonString )

还有支持泛型的重载,方便您使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多