首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NewtonSoft.Json序列化和反序列化具有IEnumerable<ISomeInterface>类型属性的类

NewtonSoft.Json序列化和反序列化具有IEnumerable<ISomeInterface>类型属性的类
EN

Stack Overflow用户
提问于 2012-08-01 15:38:06
回答 8查看 259K关注 0票数 76

我正在尝试移动一些代码来使用ASP.NET MVC Web API生成的Json数据,而不是SOAP Xml。

我在序列化和反序列化类型的属性时遇到了一个问题:

代码语言:javascript
运行
复制
IEnumerable<ISomeInterface>.

下面是一个简单的例子:

代码语言:javascript
运行
复制
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; }
 }
}

我可以使用以下命令轻松序列化SampleGroup实例:

代码语言:javascript
运行
复制
var sz = JsonConvert.SerializeObject( sampleGroupInstance );

然而,相应的反序列化失败:

代码语言:javascript
运行
复制
JsonConvert.DeserializeObject<SampleGroup>( sz );

使用此异常消息:

“无法创建类型JsonSerializationExample.ISample的实例。类型是接口或抽象类,不能是即时的。”

如果我派生一个JsonConverter,我可以像下面这样装饰我的属性:

代码语言:javascript
运行
复制
[JsonConverter( typeof (SamplesJsonConverter) )]
public IEnumerable<ISample> Samples { get; set; }

下面是JsonConverter:

代码语言:javascript
运行
复制
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?
  }
}

这个转换器解决了反序列化问题,但是我不知道如何对WriteJson方法进行编码以使序列化再次工作。

有人能帮上忙吗?

首先,这是解决问题的“正确”方法吗?

EN

Stack Overflow用户

发布于 2013-07-16 23:22:09

非常好的解决方案,谢谢!我采用了AndyDBell的问题和Cuong Le的答案,构建了一个具有两个不同接口实现的示例:

代码语言:javascript
运行
复制
public interface ISample
{
    int SampleId { get; set; }
}

public class Sample1 : ISample
{
    public int SampleId { get; set; }
    public Sample1() { }
}


public class Sample2 : ISample
{
    public int SampleId { get; set; }
    public String SampleName { get; set; }
    public Sample2() { }
}

public class SampleGroup
{
    public int GroupId { get; set; }
    public IEnumerable<ISample> Samples { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //Sample1 instance
        var sz = "{\"GroupId\":1,\"Samples\":[{\"SampleId\":1},{\"SampleId\":2}]}";
        var j = JsonConvert.DeserializeObject<SampleGroup>(sz, new SampleConverter<Sample1>());
        foreach (var item in j.Samples)
        {
            Console.WriteLine("id:{0}", item.SampleId);
        }
        //Sample2 instance
        var sz2 = "{\"GroupId\":1,\"Samples\":[{\"SampleId\":1, \"SampleName\":\"Test1\"},{\"SampleId\":2, \"SampleName\":\"Test2\"}]}";
        var j2 = JsonConvert.DeserializeObject<SampleGroup>(sz2, new SampleConverter<Sample2>());
        //Print to show that the unboxing to Sample2 preserved the SampleName's values
        foreach (var item in j2.Samples)
        {
            Console.WriteLine("id:{0} name:{1}", item.SampleId, (item as Sample2).SampleName);
        }
        Console.ReadKey();
    }
}

和SampleConverter的通用版本:

代码语言:javascript
运行
复制
public class SampleConverter<T> : CustomCreationConverter<ISample> where T: new ()
{
    public override ISample Create(Type objectType)
    {
        return ((ISample)new T());
    }
}
票数 4
EN
查看全部 8 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11754633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档