Search code examples
c#jsonserializationjson.netdeserialization

JsonProperty - Use different name for deserialization, but use original name for serialization?


I am retrieving JSON from an API. I am using newtonsoft (this is json.net right?) to deserialize this into a list of objects. It works.

Unfortunately I also need to pass this along to someone else as JSON (they can't call the API directly only I have access to it). I say unfortunately because I need to OUTPUT my JSON that is different from what is being received (the property names need to be different).

For example, I have a class called Person, with a property called Name. I want to get "People", so I make my request to that API to get JSON as above, and get back a list of Person. Unfortunately the API doesn't return me people with Name properties, it returns me pname. So to map this, I just do:

 [JsonProperty("pname")]

This is all well and good - it converts pname to name and my class now has the value! I have a list of people with names.

Now I need to give this list of objects BACK to someone else as "Name", However when I serialize my people class back to JSON, it writes out the JSON as "pname" when I really want to write it out as "Name". I suspect it's picking up the "JsonProperty".

Is there a way to just have it use pname for deserialization, but use the original property value for serialization?

Thanks!


Solution

  • You can create a custom contract resolver that sets the property names back to the ones you've defined in the C# class before serilization. Below is some example code;

    class OriginalNameContractResolver : DefaultContractResolver
    {
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            // Let the base class create all the JsonProperties 
            IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
    
            // assign the C# property name
            foreach (JsonProperty prop in list)
            {
                prop.PropertyName = prop.UnderlyingName;
            }
    
            return list;
        }
    }
    

    Use it like this;

        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Formatting = Formatting.Indented;
        if (useLongNames)
        {
            settings.ContractResolver = new OriginalNameContractResolver();
        }
    
        string response = JsonConvert.SerializeObject(obj, settings);