How to serialize object to JSON format which inherits IList and has other properties

37 Views Asked by At

I built a IData object which has a IValues property where IValues inherits from IList<ValueModel> and has a Field property.

public interface IData
{
    IValues Values { get; set; }
}

// I want to keep the inheritance with IList<ValueModel> rather than having a property, so I can directly iterate through the object.
public interface IValues : IList<ValueModel>
{
    string Field { get; set; }
}

I'm able to serialize and deserialize the object using Newtonsoft.Json, but without the Field value. I'm afraid that it is not possible to mix properties and collection-object without additional configurations (converters, binders, etc.)

Can someone share his or her thoughts ?

For a while, I thought I had an issue with the interfaces, but realised that the items were not deserialize, because I had the IsReadOnly property to True.

namespace Json
{
    internal class Program
    {
        private const string PATH = "..\\data.json"; // To update.

        static void Main(string[] args)
        {
            var data = new DataModel
            {
                Values = new ValuesModel
                {
                    Field = "test" // Not serialized.
                }
            };

            data.Values.Add(new ValueModel
            {
                Id = 1,
                Name = "Name1",
                Date = DateTime.Now,
                Comments = "Comment1"
            });

            data.Values.Add(new ValueModel
            {
                Id = 2,
                Name = "Name2",
                Comments = "Comment2"
            });

            var json = JsonConvert.SerializeObject(data, Formatting.Indented);
        
            File.WriteAllText(PATH, json);

            var json2 = File.ReadAllText(PATH);

            var data2 = JsonConvert.DeserializeObject<DataModel>(json2);
        }
    }

    #region Interfaces

    public interface IData
    {
        IValues Values { get; set; }
    }

    public interface IValues : IList<ValueModel>
    {
        string Field { get; set; }
    }

    #endregion

    #region Classes

    public class DataModel
    {
        public ValuesModel Values { get; set; }
    }

    public class ValuesModel : IValues
    {
        private readonly List<ValueModel> _values = new List<ValueModel>();

        [JsonProperty("fields")] // Has no effect.
        public string Field { get; set; }

        #region IList<ValueModel> Implementation

        public ValueModel this[int index]
        {
            get
            {
                return _values[index];
            }
            set
            {
                _values[index] = value;
            }
        }

        public int Count => _values.Count;

        public bool IsReadOnly => false; // Initial issue with True value where nothing where deserialized.

        public void Add(ValueModel value)
        {
            _values.Add(value);
        }

        public void Clear()
        {
            _values.Clear();
        }

        public bool Contains(ValueModel value)
        {
            return _values.Contains(value);
        }

        public void CopyTo(ValueModel[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public IEnumerator<ValueModel> GetEnumerator()
        {
            return _values.GetEnumerator();
        }

        public int IndexOf(ValueModel value)
        {
            return _values.IndexOf(value);
        }

        public void Insert(int index, ValueModel value)
        {
            _values.Insert(index, value);
        }

        public bool Remove(ValueModel value)
        {
            return _values.Remove(value);
        }

        public void RemoveAt(int index)
        {
            _values.RemoveAt(index);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _values.GetEnumerator();
        }

        #endregion
    }

    public class ValueModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime Date { get; set; }
        [JsonIgnore]
        public string Comments { get; set; }
    }

    #endregion
}
0

There are 0 best solutions below