0

Just want to stress out this question is irrelevant of why this technology and why not that. This is related to C# code.

I searched below but none provides solution.

Serialize a class that implements IEnumerable

Serialization on classes that implement IEnumerator

I am working on WCF Rest project in C# which is replacing .NET Remoting communication layer. I use Newtonsoft dll to serialize and de-serialize.

I have a class called MyDTO which implements IEnumerator, IEnumerable which I cannot change since this is old class and many applications in production use them. When I try to serialize MyDTO into string I do not get any error/exception message, I just get an empty array like "[]". Can anybody tell how we can serialize/deserialze class that implements IEnumerator, IEnumerable?

public class MyDTO : IEnumerator, IEnumerable

I am calling a method called ABC in OldServer.dll which gives me MyDTO object. I want to convert this to string and again from string to MyDTO.

Please let me know if you need more information. Please see below for MyDTO class which I cannot change:

[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
}

UPDATE 1:

After spending almost a day we decided to write our own method targeting MyDTO which will produce XmlDocument which is serialize. Using that same XmlDocument we will try create MyDTO object. I feel we need to just concentrate on properties that has setters. I will let you know.

Ziggler
  • 3,361
  • 3
  • 43
  • 61
  • 1
    Why are you using WCF Rest instead of ASP.NET Web API or ASP.NET Core? WCF Rest was only meant as a stop-gap measure before ASP.NET MVC – Panagiotis Kanavos Sep 16 '19 at 17:12
  • @PanagiotisKanavos.. before I joined the company it was decided that in order for us to open up our system .net remoting will be replaced by WCF. After I joined, I did research SOAP vs REST and I recommended REST. It serves our purpose I do not see REST HTTP is not going to be replaced in near/distant future – Ziggler Sep 16 '19 at 17:33
  • You did not answer his actual question. Check [this](https://stackoverflow.com/questions/43775132/difference-between-wcf-web-api-wcf-rest-and-web-service) – fredrik Sep 16 '19 at 20:44
  • Ok.. now I cannot change WCF Rest service to someother since it is already in production.. – Ziggler Sep 16 '19 at 20:45
  • I know it's out of scope for this question - but you probably should start planning for swapping that. WCF probably won't be around forever... upgrading things like this should be part of any systems life cycle management. Unless you plan for it to be decommissioned before it becomes an issue ofc – fredrik Sep 16 '19 at 21:33

1 Answers1

0

Using the almighty Json.Net

1) Create a contract resolver to serialize/deserialize specific members based on their accessibility, cause by default serialization/deserialization only happens for public members.

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) Then you can serialize your object like

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

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

3) And you can deserialize like

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

MyDTO deserializedDTO = JsonConvert.DeserializeObject<MyDTO>(serializedDTO, settings);
ChoopTwisk
  • 1,296
  • 7
  • 13
  • Thanks @Mohamed.. I will try and let you know. – Ziggler Sep 16 '19 at 17:09
  • On further analysis CreateProperties type was Object. I added Type t = typeof(MyDTO); var x = t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Now I get few props. But serialize is returning me "[]" – Ziggler Sep 16 '19 at 20:40