Making a property deserialize but not serialize with json.net

There are actually several fairly simple approaches you can use to achieve the result you want.

Let’s assume, for example, that you have your classes currently defined like this:

class Config
{
    public Fizz ObsoleteSetting { get; set; }
    public Bang ReplacementSetting { get; set; }
}

enum Fizz { Alpha, Beta, Gamma }

class Bang
{
    public string Value { get; set; }
}

And you want to do this:

string json = @"{ ""ObsoleteSetting"" : ""Gamma"" }";

// deserialize
Config config = JsonConvert.DeserializeObject<Config>(json);

// migrate
config.ReplacementSetting = 
    new Bang { Value = config.ObsoleteSetting.ToString() };

// serialize
json = JsonConvert.SerializeObject(config);
Console.WriteLine(json);

To get this:

{"ReplacementSetting":{"Value":"Gamma"}}

Approach 1: Add a ShouldSerialize method

Json.NET has the ability to conditionally serialize properties by looking for corresponding ShouldSerialize methods in the class.

To use this feature, add a boolean ShouldSerializeBlah() method to your class where Blah is replaced with the name of the property that you do not want to serialize. Make the implementation of this method always return false.

class Config
{
    public Fizz ObsoleteSetting { get; set; }

    public Bang ReplacementSetting { get; set; }

    public bool ShouldSerializeObsoleteSetting()
    {
        return false;
    }
}

Note: if you like this approach but you don’t want to muddy up the public interface of your class by introducing a ShouldSerialize method, you can use an IContractResolver to do the same thing programmatically. See Conditional Property Serialization in the documentation.

Approach 2: Manipulate the JSON with JObjects

Instead of using JsonConvert.SerializeObject to do the serialization, load the config object into a JObject, then simply remove the unwanted property from the JSON before writing it out. It’s just a couple of extra lines of code.

JObject jo = JObject.FromObject(config);

// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();

json = jo.ToString();

Approach 3: Clever (ab)use of attributes

  1. Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.
  2. Add an alternate, private property setter to the class with the same type as the original property. Make the implementation of that property set the original property.
  3. Apply a [JsonProperty] attribute to the alternate setter, giving it the same JSON name as the original property.

Here is the revised Config class:

class Config
{
    [JsonIgnore]
    public Fizz ObsoleteSetting { get; set; }

    [JsonProperty("ObsoleteSetting")]
    private Fizz ObsoleteSettingAlternateSetter
    {
        // get is intentionally omitted here
        set { ObsoleteSetting = value; }
    }

    public Bang ReplacementSetting { get; set; }
}

Leave a Comment