动态更改嵌套类型的自定义转换器

本文关键字:自定义 转换器 嵌套类型 动态 | 更新日期: 2023-09-27 18:27:06

由于架构更改,我需要根据控制器级别的API版本或客户端版本控制属性b的反序列化。

public class MyModel
{
    public string a { get; set; }
    // old: public string b { get; set; }
    public string[] b { get; set; }
}

我希望实现一个自定义转换器,在版本旧的情况下将string[]写为单个字符串。

在构造响应时,我正在反序列化父模型,并且希望仅在这一个属性上使用自定义转换器。

public class ParentModel
{
    public MyModel myModel { get; set; }
}

这意味着b的属性不起作用。如何根据需要仅为一个属性植入这样的自定义转换器(自定义转换器是通过类型而非属性名称打开的)?

动态更改嵌套类型的自定义转换器

检查以下代码

public class ParentModelJSONConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new ApplicationException("Serializable only");
        }
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            Dictionary<string, object> result = new Dictionary<string, object>();
            ParentModel myobj = obj as ParentModel;
            if (myobj != null)
            {
                // Add your conditions
                result.Add("MyKeyName", myobj.myModel);
            }
            return result;
        }
        public override IEnumerable<Type> SupportedTypes
        {
            get { return new Type[] { typeof(ParentModel) }; }
        }
    }

使用以上代码

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new ParentModelJSONConverter() });
String json = serializer.Serialize(objParentModel);

最终进行了以下手动转换。由于这是一个模式更改,旧模型可以很容易地进行硬编码:

public class CustomConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var o = (MyModel)value;
        writer.WriteStartObject();
        writer.WritePropertyName("a");
        writer.WriteValue(o.a);
        writer.WritePropertyName("b");
        writer.WriteValue(o.b[0]);
        writer.WriteEndObject();
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MyModel);
    }
    //...
}

}