【问题标题】:How to serialize/deserialze a class that implements IEnumerator, IEnumerable?如何序列化/反序列化实现 IEnumerator、IEnumerable 的类?
【发布时间】:2020-01-17 12:54:46
【问题描述】:

只是想强调一下,这个问题与为什么使用这种技术以及为什么不使用这种技术无关。这与C#代码有关。

我在下面搜索但没有提供解决方案。

Serialize a class that implements IEnumerable

Serialization on classes that implement IEnumerator

我正在使用 C# 开发 WCF Rest 项目,该项目正在替换 .NET Remoting 通信层。我使用 Newtonsoft dll 进行序列化和反序列化。

我有一个名为MyDTO 的类,它实现了IEnumeratorIEnumerable,我无法更改它,因为这是旧类并且生产中的许多应用程序都使用它们。当我尝试将MyDTO 序列化为字符串时,我没有收到任何错误/异常消息,我只是得到一个空数组,如“[]”。谁能告诉我们如何序列化/反序列化实现 IEnumeratorIEnumerable 的类?

public class MyDTO : IEnumerator, IEnumerable

我在 OldServer.dll 中调用了一个名为 ABC 的方法,它为我提供了 MyDTO 对象。我想将其转换为字符串,然后再从字符串转换为 MyDTO。

如果您需要更多信息,请告诉我。请参阅下面的MyDTO 我无法更改的课程:

[Serializable]
public class MyDTO : IEnumerator, IEnumerable
{
    #region Inner Types

    internal class MyObjComparer : IComparer<MyObj>
    {
        public int Compare(MyObj x, MyObj y)
        {
            return x.InputCode.CompareTo(y.InputCode);
        }
    }
    #endregion

    #region Variables

    private List<MyObj> myObjList;
    private string selectedObjectMessage;

    private bool containSequenceNo = false;

    private bool sortEnabled;
    private bool filterEnabled;
    private IComparer<MyObj> objectComparer;
    #endregion

    #region Constructors

    public MyDTO()
    {
        this.myObjList = new List<MyObj>();
        this.selectedObjectMessage = string.Empty;
    }

    public MyDTO(List<MyObj> objects)
    {
        this.myObjList = objects;
        this.selectedObjectMessage = string.Empty;
    }

    public MyDTO(IComparer<MyObj> argSortComparer)
        : this()
    {
        this.objectComparer = argSortComparer;
    }

    public MyDTO(List<MyObj> argErrors, IComparer<MyObj> argSortComparer)
        : this(argErrors)
    {
        this.objectComparer = argSortComparer;
    }

    public MyDTO(List<MyObj> argErrors, IComparer<MyObj> argSortComparer, bool argSortEnabled)
        : this(argErrors, argSortComparer)
    {
        this.sortEnabled = argSortEnabled;
    }

    #endregion

    #region Properties

    public string selectedObjectMessage
    {
        get { return this.selectedObjectMessage; }
        set
        {
            if (value == null)
                value = string.Empty;

            this.selectedObjectMessage = value;
        }
    }

    public int Count
    {
        get { return this.myObjList.Count; }
    }

    public bool ErrorsContainsSequenceNo
    {
        get { return this.containSequenceNo; }
        set { this.containSequenceNo = value; }
    }

    public List<MyObj> myObjList            
    {                                          
        get { return this.myObjList; }         
        set { this.myObjList = value; } 
    }     

    public MyDTO WithoutEmptyMyObjects
    {
        get
        {
            MyDTO objs = new MyDTO();

            foreach (MyObj obj in this.myObjList)
            {
                if (!string.IsNullOrEmpty(obj.InputCode))
                    objs.Add(obj);
            }
            return objs;
        }
    }
    #endregion
}

更新 1:

花了将近一天的时间后,我们决定编写自己的针对 MyDTO 的方法,该方法将生成可序列化的 XmlDocument。使用相同的 XmlDocument,我们将尝试创建 MyDTO 对象。我觉得我们只需要专注于有 setter 的属性。我会告诉你的。

【问题讨论】:

  • 为什么使用 WCF Rest 而不是 ASP.NET Web API 或 ASP.NET Core? WCF Rest 只是在 ASP.NET MVC 之前作为权宜之计
  • @PanagiotisKanavos.. 在我加入公司之前,我们决定为了开放我们的系统,.net 远程处理将被 WCF 取代。加入后,我研究了 SOAP 与 REST,并推荐了 REST。它符合我们的目的,我认为 REST HTTP 不会在近期/遥远的将来被取代
  • 你没有回答他的实际问题。检查this
  • 好的..现在我无法将 WCF Rest 服务更改为其他服务,因为它已经在生产中..
  • 我知道这超出了这个问题的范围 - 但您可能应该开始计划交换它。 WCF 可能不会永远存在......升级这样的东西应该是任何系统生命周期管理的一部分。除非您计划在它成为问题之前将其退役

标签: c# serialization json.net ienumerable ienumerator


【解决方案1】:

使用万能的Json.Net

1) 创建一个合约解析器以根据特定成员的可访问性对其进行序列化/反序列化,因为默认情况下,序列化/反序列化仅针对公共成员发生。

public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                        .Select(p => base.CreateProperty(p, memberSerialization))
                    .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                               .Select(f => base.CreateProperty(f, memberSerialization)))
                    .ToList();
        props.ForEach(p => { p.Writable = true; p.Readable = true; });
        return props;
    }
}

2) 然后你可以像这样序列化你的对象

var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver() };

// dtoInstance is your dto instance you wish to serialize.
string serializedDTO = JsonConvert.SerializeObject(dtoInstance, settings);

3) 你可以像这样反序列化

var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver() };  

MyDTO deserializedDTO = JsonConvert.DeserializeObject<MyDTO>(serializedDTO, settings);

【讨论】:

  • 谢谢@Mohamed.. 我会尽力让你知道的。
  • 进一步分析 CreateProperties 类型是 Object。我添加了 Type t = typeof(MyDTO); var x = t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);现在我得到了一些道具。但是序列化返回我“[]”
猜你喜欢
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 2012-07-30
相关资源
最近更新 更多