如何在反序列化过程中检测属性是否在输入处

本文关键字:是否 输入 属性 过程中 反序列化 检测 | 更新日期: 2023-09-27 18:12:25

我有以下类:

[DataContract]
public class MyMessage
{
    [DataMember(IsRequired = false)]
    public string Foo { get; set; }
    [DataMember(IsRequired = false)]
    public string Bar { get; set; }
    public void NotifyPropertyFound( string propName )
    {
        ...
    }
}

我需要反序列化以下Json输入:

{ "Foo": null,
  "Melda": 123
}

我需要反序列化器调用方法NotifyPropertyFound两次:一次使用参数"Foo"(我在我的类中有),再一次使用参数"Melda"(我没有)。

我正在玩IContractResolverJsonConverter,但它们似乎都没有提供调用NotifyPropertyFound方法的机会。任何想法?

编辑

我可以使用IValueProvider检测"Foo"。但是我仍然需要检测"Melda"

如何在反序列化过程中检测属性是否在输入处

也许您可以将属性更改为由私有字段而不是auto属性支持。然后,您可以尝试在默认反序列化器调用的setter中调用该方法。

另一种选择是编写自己的反序列化器。

您可以使用自定义JsonConverter获得您想要的结果,如以下所示:

class MyMessageConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(MyMessage));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        MyMessage msg = jo.ToObject<MyMessage>();
        foreach (JProperty prop in jo.Properties())
        {
            msg.NotifyPropertyFound(prop.Name);
        }
        return msg;
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"{ ""Foo"": null, ""Melda"": 123 }";
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Converters.Add(new MyMessageConverter());
        MyMessage msg = JsonConvert.DeserializeObject<MyMessage>(json, settings);
    }
}
[DataContract]
public class MyMessage
{
    [DataMember(IsRequired = false)]
    public string Foo { get; set; }
    [DataMember(IsRequired = false)]
    public string Bar { get; set; }
    public void NotifyPropertyFound(string propName)
    {
        // Write to the console each time this method is called
        Console.WriteLine(propName);
    }
}
输出:

Foo
Melda