如果使用自定义 JsonConverter 属性 未包含在 json 字符串中,如何在反序列化时设置值

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

我有一个 Json 字符串用于某个对象的列表,这个 Json 字符串不包括我的对象的属性之一。我正在寻找一种方法来设置丢失的 属性 值,同时将 Json 字符串反序列化为 object.I 有一种方法可以在反序列化完成后设置它,但如果我可以设置它会更喜欢它它在反序列化时。

我尝试使用自定义 JsonConverter 但它不会作为相应的 属性 执行,而不是 Json 字符串的一部分,如果我可以注入,任何其他方式也可以反序列化时缺少 属性 中的值。

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; }
}

自定义Json转换器

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;
    }
}

反序列化

    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);
    }

您可以创建一个自定义转换器,让 Newtonsoft 读取和解析 json 中存在的所有属性,并且您可以手动为缺失的属性赋值:

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();
    }
}

我使用的是随机值,但您可以指定任何您想要的值。

用法:

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

使用这种方法,您不必用 JsonConverterAttribute.

修饰 TestClassInternalID 属性

更新:非通用 JsonConverter 版本

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();
    }
}