Search code examples
c#serializationjson.netdeserialization

How to deserialize a read only List with Json.Net


I have a class with an internal list. I don't want the user of this class to be able to interact with the list directly, since I want to both keep it sorted and to run a calculation (which depends on the order) before returning it.

I expose

AddItem(Item x) 

and a

IEnumerable<Item> Items
{
     get { // returns a projection of internal list }
}

Serialization worked OK, but deserializing left the list empty. I figured it was because I didn't have a setter. So I added one that allowed you to set the list, but only if the internal list was empty. But this didn't solve the problem, turns out NewtonSoft does not call the setter, it only calls the getter to get the list, and then adds each item to it, which, since my getter returns a projected list, those items get added to an object that is immediately disposed once deserialization is done.

How do I maintain a read-only access to my list, while at the same time allowing for somewhat straightforward deserialization?


Solution

  • What worked for me was the following:

    [JsonProperty(PropertyName = "TargetName")]
    private List<SomeClass> _SomeClassList { get; set; }
    public IReadOnlyList<SomeClass> SomeClassList
    {
        get
        {
            return this._SomeClassList.AsReadOnly();
        }
    }
    

    Then, make a function to prevent SomeClassList to be serialized:

    public bool ShouldSerializeSomeClassList() { return false; }
    

    See https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm (thanks Peska)