0

My question is almost answered by this: https://stackoverflow.com/a/24224465/454754 But I can't really figure out how to make it work when my property is replaced (i.e. I have a new version of the object basically).

Specifically I have a class

public class Something {
    public decimal? Fee { get; set;}
}

Which I have serialized using JSON.Net and stored in an external store (database).

Now I want to have a new version of the same class:

public class Something {
    public Fee Fee { get; set;}
}

public class Fee {
    public decimal? Amount { get; set; }
    public int Type { get; set; }
}

However i need to be able to deserialize old instances into new instance (and if i serialize them again they should be saved as the new version).

I don't mind adding new internal/private properties as long as these are not serialized.

What I would like to avoid is a new public property like NewFee or some such.

I am probably missing something here, it feels like it should be possible with all the hooks provided by JSON.Net.

Esben Bach
  • 664
  • 4
  • 23
  • I'd probably be looking into custom deserializers. – Fildor Jan 20 '21 at 13:34
  • 2
    Have a look into this: [Custom Deserialization using Json.NET](https://stackoverflow.com/questions/40439290/custom-deserialization-using-json-net) – Fildor Jan 20 '21 at 13:36
  • For System.Text.Json: [How to write custom converters for JSON serialization (marshalling) in .NET](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0) – Fildor Jan 20 '21 at 13:38

1 Answers1

0

Thanks to @Fildor for leading me in the right direction. The answer was deceptively simple, add a type converter and decorate the new property with the converter.

public class Something {
    [JsonConverter(typeof(FeeConverter))]
    public Fee Fee { get; set;}
}

public class Fee {
    public decimal? Amount { get; set; }
    public int Type { get; set; }
}

public class FeeConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Float || reader.TokenType == JsonToken.Integer)
        {
            var property = JValue.Load(reader);
            return new Fee() { Amount = property.Value<decimal>() };
        }

        return serializer.Deserialize(reader, objectType);
    }

    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => false;
}
Esben Bach
  • 664
  • 4
  • 23