Json.net:如何在反序列化期间检测属性是否处于输入状态?

时间:2014-07-11 13:52:28

标签: c# .net json serialization json.net

我有以下课程:

[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"(我不会# 39; t)。

我正在玩IContractResolverJsonConverter,但他们似乎都没有机会调用NotifyPropertyFound方法。有什么想法吗?

修改

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

2 个答案:

答案 0 :(得分:0)

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

另一种方法是编写自己的反序列化器。

答案 1 :(得分:0)

您可以使用自定义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