如何配置JSON.net解串器来跟踪缺少的属性? [英] How to configure JSON.net deserializer to track missing properties?

查看:147
本文介绍了如何配置JSON.net解串器来跟踪缺少的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Sample类:

public class ClassA
{
    public int Id { get; set; }
    public string SomeString { get; set; }
    public int? SomeInt { get; set; }
}

默认解串器:

var myObject = JsonConvert.DeserializeObject<ClassA>(str);



对于两个不同的输入

Create the same object for two different inputs

{"Id":5}

{"Id":5,"SomeString":null,"SomeInt":null} 

如何跟踪,在反序列化过程中缺失的属性,并保留相同的行为?有没有一种方法来覆盖一些JSON.net串行方法(例如DefaultContractResolver类方法)才达到这一点。例如:

How can I track properties that were missing during deserialization process and preserve the same behavior? Is there a way to override some of JSON.net serializer methods (e.g. DefaultContractResolver class methods) to achive this. For example:

List<string> missingProps;
var myObject = JsonConvert.DeserializeObject<ClassA>(str, settings, missingProps);

有关的第一个输入列表应该包括缺少的属性的名称(SomeString,SomeInt )和第二个输入它应该是空的。反序列化对象是一样的。

For the first input list should contains the names of the missing properties ("SomeString", "SomeInt") and for second input it should be empty. Deserialized object remains the same.

推荐答案

要找到反序列化期间,空/未定义的令牌另一种方法是编写自定义的 JsonConverter ,这是自定义的转换器,它可以同时报告省略标记(如的一个例子{ID:5} )和空标记(如 {ID:5,SomeString:空,SomeInt:空}

Another way to find null/undefined tokens during De-serialization is to write a custom JsonConverter , Here is an example of custom converter which can report both omitted tokens (e.g. "{ 'Id':5 }") and null tokens (e.g {"Id":5,"SomeString":null,"SomeInt":null})

public class NullReportConverter : JsonConverter
{
    private readonly List<PropertyInfo> _nullproperties=new List<PropertyInfo>();
    public bool ReportDefinedNullTokens { get; set; }

    public IEnumerable<PropertyInfo> NullProperties
    {
        get { return _nullproperties; }
    }

    public void Clear()
    {
        _nullproperties.Clear();
    }

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        existingValue = existingValue ?? Activator.CreateInstance(objectType, true);

        var jObject = JObject.Load(reader);
        var properties =
            objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        foreach (var property in properties)
        {
            var jToken = jObject[property.Name];
            if (jToken == null)
            {
                _nullproperties.Add(property);
                continue;
            }

            var value = jToken.ToObject(property.PropertyType);
            if(ReportDefinedNullTokens && value ==null)
                _nullproperties.Add(property);

            property.SetValue(existingValue, value, null);
        }

        return existingValue;
    }

    //NOTE: we can omit writer part if we only want to use the converter for deserializing
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var objectType = value.GetType();
        var properties =
            objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        writer.WriteStartObject();
        foreach (var property in properties)
        {
            var propertyValue = property.GetValue(value, null);
            writer.WritePropertyName(property.Name);
            serializer.Serialize(writer, propertyValue);
        }

        writer.WriteEndObject();
    }
}

注意:我们可以忽略的作家的一部分如果我们并不需要使用它的序列化对象

用法示例:

class Foo
{
    public int Id { get; set; }
    public string SomeString { get; set; }
    public int? SomeInt { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var nullConverter=new NullReportConverter();

        Console.WriteLine("Pass 1");
        var obj0 = JsonConvert.DeserializeObject<Foo>("{\"Id\":5, \"Id\":5}", nullConverter);
        foreach(var p in nullConverter.NullProperties)
            Console.WriteLine(p);

        nullConverter.Clear();

        Console.WriteLine("Pass2");
        var obj1 = JsonConvert.DeserializeObject<Foo>("{\"Id\":5,\"SomeString\":null,\"SomeInt\":null}" , nullConverter);
        foreach (var p in nullConverter.NullProperties)
            Console.WriteLine(p);

        nullConverter.Clear();

        nullConverter.ReportDefinedNullTokens = true;
        Console.WriteLine("Pass3");
        var obj2 = JsonConvert.DeserializeObject<Foo>("{\"Id\":5,\"SomeString\":null,\"SomeInt\":null}", nullConverter);
        foreach (var p in nullConverter.NullProperties)
            Console.WriteLine(p);
    }
}

这篇关于如何配置JSON.net解串器来跟踪缺少的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆