Neeraj Kumar Gupta
Neeraj Kumar Gupta

Reputation: 2363

How to set the value while deserialization if property not included in json string using custom JsonConverter

I have a Json string for a list of some object, this Json string does not include one of the properties from my object. I am looking for a way to set that missing property value while deserializing the Json string to object.I have a work around to set it after completion of deserialization but would prefer it if I can set it while deserialization.

I tried using custom JsonConverter but it does not get executed as a respective property not a part of Json string, any other way is also fine if I can inject value in missing property while deserialization.

Class

public class TestClass
{
    [JsonConverter(typeof(InternalIDConverter))]
    public int InternalID { get; set; }
    public int IdRemittance { get; set; }
    public string IDCountry { get; set; }
    public string OperationAction { get; set; }
    public bool BusinessToBusiness { get; set; }
}

Custom JsonConverter

public class InternalIDConverter : JsonConverter
{

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        //Doing my work here
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}

Deserialization

    private void button11_Click(object sender, EventArgs e)
    {
        string json = "[{\"IDCountry\":\"AK\",\"BusinessToBusiness\":false,\"IdRemittance\":2,\"OperationAction\":\"U\"},{\"IDCountry\":\"AK\",\"BusinessToBusiness\":true,\"IdRemittance\":14,\"OperationAction\":\"U\"}]";

        var data = JsonConvert.DeserializeObject<List<TestClass>>(json);
    }

Upvotes: 2

Views: 2111

Answers (1)

Peter Csala
Peter Csala

Reputation: 22714

You can create a custom converter where you let Newtonsoft read and parse all the properties that are present in the json and you can manually assign values to the missing ones:

public class TestClassConverter : JsonConverter<TestClass>
{
    private static readonly Random rand = new Random();
    public override TestClass ReadJson(JsonReader reader, Type objectType, TestClass existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        //Let Newtonsoft do the heavy lifting
        var jObject = JObject.Load(reader);
        var target = new TestClass();
        serializer.Populate(jObject.CreateReader(), target);

        //Set the intact property manually
        target.InternalID = rand.Next();
        return target;
    }

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

I've used random, but you can assign whatever value you want.

Usage:

var data = JsonConvert.DeserializeObject<List<TestClass>>(json, converters: new TestClassConverter());

With this approach you don't have to decorate TestClass's InternalID property with a JsonConverterAttribute.


UPDATE: Non-generic JsonConverter version

public class TestClassConverter : JsonConverter
{
    private static readonly Random rand = new Random();
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TestClass);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);
        var target = new TestClass();
        serializer.Populate(jObject.CreateReader(), target);

        target.InternalID = rand.Next();
        return target;
    }

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

Upvotes: 1

Related Questions