2

Using C#, .Net v4.0 - Given the following structure:

public interface IInterface {...}

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

I do have parameterless constructor defined in the class.

Upon receiving a JSON object, I attempt to deserialize MyClass and receive an error along the lines of:

no parameterless constructor defined for this object

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

I have also tried without the SimpletypeResolver()

I have seen a few posts that seem to hover around what I'm looking for, but not quite there - unless I'm missing something.

MyClass implements an interface, no default constructor can be defined in an interface. Got it. So how can I deserialize MyClass objects?

Community
  • 1
  • 1
ElHaix
  • 12,846
  • 27
  • 115
  • 203

2 Answers2

3

You need to tell your deserializer want concrete class type to convert the json to. One way to do that is to implement the JsonConverter class in Json.Net.

Complete contrived working example.

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);
    }
}
cgotberg
  • 2,045
  • 1
  • 18
  • 18
  • I tried your suggestions, but am still getting the same error when I use `DeserializeObject...` - *Could not create an instance of type IInterface. Type is an interface or abstract class and cannot be instantiated*. `MyClass` is `MyClass:IInterface` – ElHaix Oct 16 '13 at 15:53
  • Updated answer to one that is contrived but does work in a unit test. – cgotberg Oct 17 '13 at 17:20
  • I ended up using the solution suggested here: http://stackoverflow.com/questions/19413475/why-does-this-ploymorphic-list-property-go-null-when-adding-additional-objects-t, creating two generic types, and removing the interface. This may have some consequences during unit testing time, but it works. I am however marking your answer as accepted, and will probably revisit it in the near future. Thank you. – ElHaix Oct 18 '13 at 15:51
-3

You can use Newtonsoft.Json library to Serialize/Desirialize .NET objects Like this:

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

Also there is overloads with support of generics for you convinience.

igorGIS
  • 1,888
  • 4
  • 27
  • 41