1

I have an object I am serializing into JSON then deserializing back.

The structure of one of the properties has changed and now deserializing crashes, so I need to ignore deserializing that property for now.

I can ignore the property completely with [JsonIgnore, JsonProperty(Required = Required.Default)], but that also ignores the property from serialization - which needs to stay so no data is lost, even if it isn't' being serialized at this moment.

Moffen
  • 1,817
  • 1
  • 14
  • 34

3 Answers3

2

There is an answer here, although it's a bit old: https://stackoverflow.com/a/31732029/12431728 However, it still seems viable to me, I'm not aware of a better / different way to do it. That answer suggests marking the real property with JsonIgnore and creating a "get-only proxy property."

Then it goes on to suggest creating a custom ContractResolver if you need this functionality for many properties (AKA reusable solution).

Matt U
  • 4,970
  • 9
  • 28
  • Hey Matt great suggestion here, I'm looking into the custom ContractResolver now – Moffen Nov 26 '19 at 01:09
  • @moffin do you not want ultimately to be able to deserialise your property from json? If so, it seems here more like you want to have a way of assigning data from your json if it exists and ignoring if it doesn't. This functionality doesn't really seem to be afforded by having an ignored property with an accessible getter – Jack Nov 26 '19 at 01:26
  • 1
    @Jack I want to ignore data even when it is there. The specific field has changed from a string to an object and I just want to ignore loading it for now while still saving it – Moffen Nov 26 '19 at 01:29
1

You could use a JsonContractResolver to set the JsonProperty.ShouldDeserialize property as seen in one of the test suites of Newtonsoft.Json.

For Example,

public class ShouldDeserializeContractResolver : DefaultContractResolver
{
    public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name);

        if (shouldDeserializeMethodInfo != null)
        {
            property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); };
        }

        return property;
    }
}

Example Code

var instance = new RootObject { ID = 2, DisplayName = "John Doe" };
var json = JsonConvert.SerializeObject(instance);
var settings = new JsonSerializerSettings
{
  ContractResolver = ShouldDeserializeContractResolver.Instance
};
Console.WriteLine(json);

var deserializedInstance = JsonConvert.DeserializeObject<RootObject>(json, settings);
Console.WriteLine($"Deserialized => Id={deserializedInstance.ID}, Name={deserializedInstance.DisplayName} ");

Where RootObject is defined as

public class RootObject
{
    public int ID { get; set; }
    public string DisplayName { get; set; }

    public bool ShouldDeserializeDisplayName() => false;    
}

Output

{"ID":2,"DisplayName":"John Doe"}  //During Serialization
Deserialized => Id=2, Name=        // During Deserialization  
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
0

You could serialise and deserialise from a JObject as in the link from Amadeu Antunes, although this solution is rather inelegant, as suddenly you've thrown loose typing into the mix.

Another potentially easier possibility is that if you have access to all of the json objects that you are deserialising from, you could do a bulk update in notepad++, ssms or whatever and just add in some default value into the json files.

Jack
  • 871
  • 1
  • 9
  • 17