【问题标题】:How to set the value while deserialization if property not included in json string using custom JsonConverter如果属性未包含在使用自定义 JsonConverter 的 json 字符串中,如何在反序列化时设置值
【发布时间】:2021-06-17 10:30:51
【问题描述】:

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

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

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

自定义 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;
    }
}

反序列化

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

【问题讨论】:

    标签: c# .net json.net json-deserialization


    【解决方案1】:

    您可以创建一个自定义转换器,让 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();
        }
    }
    

    【讨论】:

    • JsonConverter 没有通用类来传递我的 TestClass,我使用的是 Newtonsoft.Json,Version=8.0.0.0
    • @NeerajKumarGupta 您也可以使用与非通用 JsonConverter 中相同的逻辑。在 ReadJson 中,您可以访问阅读器和序列化程序。我建议将该转换器应用于整个 TestClass 而不是单个属性。在下午晚些时候,我可以更新我的答案以包含该版本。
    • @NeerajKumarGupta 我已经更新了我的帖子,请检查一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    相关资源
    最近更新 更多