Reputation: 2363
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
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