Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
535 views
in Technique[技术] by (71.8m points)

c# - NewtonSoft.Json Serialize and Deserialize class with property of type IEnumerable<ISomeInterface>

I am trying to move some code to consume ASP.NET MVC Web API generated Json data instead of SOAP Xml.

I have run into a problem with serializing and deserializing properties of type:

IEnumerable<ISomeInterface>.

Here is a simple example:

public interface ISample{
  int SampleId { get; set; }
}
public class Sample : ISample{
  public int SampleId { get; set; }
}
public class SampleGroup{
  public int GroupId { get; set; }
  public IEnumerable<ISample> Samples { get; set; }
 }
}

I can serialize instances of SampleGroup easily with:

var sz = JsonConvert.SerializeObject( sampleGroupInstance );

However the corresponding deserialize fails:

JsonConvert.DeserializeObject<SampleGroup>( sz );

with this exception message:

"Could not create an instance of type JsonSerializationExample.ISample. Type is an interface or abstract class and cannot be instantated."

If I derive a JsonConverter I can decorate my property as follows:

[JsonConverter( typeof (SamplesJsonConverter) )]
public IEnumerable<ISample> Samples { get; set; }

Here is the JsonConverter:

public class SamplesJsonConverter : JsonConverter{
  public override bool CanConvert( Type objectType ){
    return ( objectType == typeof (IEnumerable<ISample>) );
  }

  public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer ){
    var jA = JArray.Load( reader );
    return jA.Select( jl => serializer.Deserialize<Sample>( new JTokenReader( jl ) ) ).Cast<ISample>( ).ToList( );
  }

  public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer ){
    ... What works here?
  }
}

This converter solves the deserialization problem but I cannot figure how to code the WriteJson method to get serialization working again.

Can anybody assist?

Is this a "correct" way to solve the problem in the first place?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You don't need to use JsonConverterAttribute, just keep your model clean and use CustomCreationConverter instead, the code is simpler:

public class SampleConverter : CustomCreationConverter<ISample>
{
    public override ISample Create(Type objectType)
    {
        return new Sample();
    }
}

Then:

var sz = JsonConvert.SerializeObject( sampleGroupInstance );
JsonConvert.DeserializeObject<SampleGroup>( sz, new SampleConverter());

Documentation: Deserialize with CustomCreationConverter


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...