【问题标题】:Property-based type resolution in JSON.NETJSON.NET 中基于属性的类型解析
【发布时间】:2011-08-09 14:10:10
【问题描述】:

是否可以基于 JSON 对象的属性使用 JSON.NET 覆盖类型解析?基于现有的 API,我似乎需要一种接受 JsonPropertyCollection 并返回要创建的 Type 的方法。

注意:我知道TypeNameHandling attribute,但这增加了$type 属性。我无法控制源 JSON。

【问题讨论】:

    标签: c# .net json.net


    【解决方案1】:

    这似乎是通过创建自定义JsonConverter 并在反序列化之前将其添加到JsonSerializerSettings.Converters 来处理的。

    nonplus 在 Codeplex 上的 JSON.NET discussions board 上留下了一个方便的示例。我已修改示例以返回自定义 Type 并遵循默认创建机制,而不是当场创建对象实例。

    abstract class JsonCreationConverter<T> : JsonConverter
    {
        /// <summary>
        /// Create an instance of objectType, based properties in the JSON object
        /// </summary>
        protected abstract Type GetType(Type objectType, JObject jObject);
    
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer)
        {
            JObject jObject = JObject.Load(reader);
    
            Type targetType = GetType(objectType, jObject);
    
            // TODO: Change this to the Json.Net-built-in way of creating instances
            object target = Activator.CreateInstance(targetType);
    
            serializer.Populate(jObject.CreateReader(), target);
    
            return target;
        }
    }
    

    这里是示例用法(也如上所述更新):

    class VehicleConverter : JsonCreationConverter<Vehicle>
    {
        protected override Type GetType(Type objectType, JObject jObject)
        {
            var type = (string)jObject.Property("Type");
            switch (type)
            {
                case "Car":
                    return typeof(Car);
                case "Bike":
                    return typeof(Bike);
            }
    
            throw new ApplicationException(String.Format(
                "The given vehicle type {0} is not supported!", type));
        }
    }
    

    【讨论】:

    • 未实现的抽象WriteJson方法呢?
    • @CanPoyrazoğlu 您需要覆盖属性 CanWrite 并将其设置为 false。这将使转换器回退到其默认行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-11
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多