【问题标题】:DataContractJsonSerializer and List<Interface>DataContractJsonSerializer 和 List<Interface>
【发布时间】:2017-07-25 11:15:27
【问题描述】:

在我的代码中,我必须序列化 List 其中 IModel 是具体类 Model

的接口

这里是他们的一些伪代码:

public interface IModel
{
    string Codice { get; set; }
    int Position { get; }
}

[DataContract]
public class Model : IModel
{
    public Model(string Codice, int position)
    {
        this.Codice = Codice;
        this.position = position;

    }
    [DataMember(Name = "codice")]
    public string Codice { get; set; }
    [DataMember(Name = "position")]
    int position;
    public int Position { get { return position; } }
}

看完this post我写道:

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(List<IModel>), new[] { typeof(Model) });
using (FileStream writer = File.Create(@"c:\temp\modello.json"))
        {
            jsonSerializer.WriteObject(writer, myList);
        }

它可以工作,但很难看,输出包含元素类型的字段,"__type":"Model:#SomeProjectName"。 当列表声明为 List 时,是否有另一种方法可以轻松地序列化列表,而它包含实现该接口的唯一具体类的元素?我尝试了一些强制转换,但出现编译错误或运行时异常。

我想说明,在我之前的实现中,我将所有项目从 List 复制到 List 中,这是 DataContractJsonSerializer 已知的类型。事实上,我确信任何 IModel 都是 Model

【问题讨论】:

  • 为什么不序列化具体类呢?这种情况下使用接口的目的是什么?
  • 也许可以试试这个:stackoverflow.com/questions/8513042/…
  • @Ben 该接口被创建为具有抽象层,现在所有代码都使用该接口而不是实现类。在写它的那一刻,这似乎是一个好主意,现在它就在那里,但它不是绝对必要的
  • 您之前的实现有什么问题?我只是想了解你的想法:)

标签: c# datacontractjsonserializer


【解决方案1】:

为什么你需要一个接口来实现这样的实现? 我建议您通过http://json2csharp.com/ 为您的 JSON 生成 C# 类。完成后,粘贴这些类并找到 &lt;RootObject&gt; 类,然后使用您在问题中提到的 code 对其进行序列化

【讨论】:

    【解决方案2】:

    这是一个使用 AutoMapper 的解决方案。我通过向Position 添加了一个私有设置器来更改您实现的类。我希望这对你来说没问题。

    List<IModel> sourceList = new List<IModel> {new Model("A", 1), new Model("B", 2)};
    
    AutoMapper.Mapper.Initialize(a => a.CreateMap<IModel, Model>());
    List<Model> targetList = AutoMapper.Mapper.Map<List<IModel>, List<Model>>(sourceList);
    
    AutoMapper.Mapper.Initialize(a =>
    {
        a.CreateMap<Model, Model>();
        a.CreateMap<Model, IModel>().ConstructUsing(Mapper.Map<Model, Model>);
    });
    
    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(List<Model>), new[] { typeof(Model) });
    using (FileStream writer = File.Create(@"c:\temp\modello.json"))
    {
        jsonSerializer.WriteObject(writer, targetList);
    }
    
    DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<Model>));
    MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(File.ReadAllText(@"c:\temp\modello.json")));
    List<Model> targetListFromFile = (List<Model>)js.ReadObject(ms);
    List<IModel> sourceListFromFile = AutoMapper.Mapper.Map<List<Model>, List<IModel>>(targetListFromFile);
    

    界面:

    public interface IModel
    {
        string Codice { get; set; }
        int Position { get; }
    }
    

    类:

    [DataContract]
    public class Model : IModel
    {
        public Model(string Codice, int position)
        {
            this.Codice = Codice;
            Position = position;
        }
    
        [DataMember(Name = "codice")]
        public string Codice { get; set; }
        [DataMember(Name = "position")]
        public int Position { get; private set; }
    }
    

    文件如下所示:

    [{
        "codice": "A",
        "position": 1
    },
    {
        "codice": "B",
        "position": 2
    }]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-21
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      相关资源
      最近更新 更多