C#JSON反序列化:我可以拦截反序列化并可选择更改结果吗?

Jos*_*osh 7 c# json json.net

我们有一些JSON,我们正在反序列化为C#中的强类型对象图.但是,我们有一个问题:有时在一个属性中JSON(例如,空字符串)中存在一个"空"值,该属性映射到我们模型中的布尔值.

在我们的例子中,我们知道100%的时间,我们可以将这些"空白"值转换为布尔值false.

但是,我尝试过的JSON反序列化器对此并不了解(可以理解).

我一直试图找到一种方法来拦截每个属性的反序列化,并可选择覆盖输出.即,如果有一个"拦截器"方法我可以注册,看起来像这样:

    public Boolean JsonDeserializationInterceptor(String rawJson, System.Type targetType, out object result)
    {
        Boolean overrodeValue = false;
        result = null;
        if(targetType == typeof(System.Boolean))
        {
            overrodeValue = true;
            // We'll pretend that we're interpreting the string "Yes" as
            // true, and all other values are false.
            if (rawJson != null && rawJson.ToLower() == "\"yes\"")
                result = true;
            else
                result = false;
        }

        return overrodeValue;
    }
Run Code Online (Sandbox Code Playgroud)

当然,这只是假设,但希望它能让您了解我想要实现的目标.

在我的研究中,我无法找到一种方法来做到这一点.我查看了Json.NET,System.Runtime.Serialization.Json.DataContractJsonSerializerSystem.Web.Script.Serialization.JavaScriptSerializer.我打赌有办法做到这一点,我只是无法弄明白.

编辑:我想你可能能够使用JsonConverterAttribute,但到目前为止我还没有能够使用它.

Ath*_*ari 6

JsonConverter为原始类型编写自定义非常简单:

using System;
using Newtonsoft.Json;

namespace So16972364JsonDeserializeConverter
{
    class BoolConverter : JsonConverter
    {
        public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
        {
            serializer.Serialize(writer, value);
        }

        public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            switch (reader.TokenType) {
                case JsonToken.String:
                    if ((string)reader.Value == "")
                        return false;
                    break;
                case JsonToken.Boolean:
                    return reader.Value;
            }
            throw new JsonReaderException("Expected boolean or empty string.");
        }

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

    class Program
    {
        const string json = @"
{
    b1: true,
    b2: false,
    b3: ''
}
";

        static void Main ()
        {
            Foo foo = JsonConvert.DeserializeObject<Foo>(json, new JsonSerializerSettings {
                Converters = { new BoolConverter() }
            });
            Console.WriteLine(JsonConvert.SerializeObject(foo, Formatting.Indented));
            Console.ReadKey();
        }
    }

    class Foo
    {
        public bool b1, b2, b3;
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码覆盖所有布尔值的反序列化.如果您只需要特定成员,则需要申请JsonConverterAttribute.