代码之家  ›  专栏  ›  技术社区  ›  Mauro

使用属性定义要使用的JsonConverter

  •  2
  • Mauro  · 技术社区  · 7 年前

    JsonConverter 对于使用特定属性装饰的属性,在本例中 [DataType(DataType.PostalCode)]

    我已经有一个习惯了 JsonConverter CanConvert 方法如下:

    public override bool CanConvert(Type objectType) => objectType == typeof(string);
    

    我怎样才能确保 PostcodeJsonConverter PostalCode 所有物

    [DataType(DataType.PostalCode)]
    public string Postcode { get; set; }
    

    我试过以下方法,但我怀疑 DataType 属性此时不可用。

    public override bool CanConvert(Type objectType) => 
        objectType == typeof(string) && 
        objectType.GetCustomAttributes(true)
                  .OfType<DataTypeAttribute>()
                  .Any(dta => dta.DataType == DataType.PostalCode);
    

    我需要按照以下方式装饰我的模型吗?

    [DataType(DataType.PostalCode)]
    [JsonConverter(typeof(PostcodeJsonConverter))]
    public string Postcode { get; set; }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Brian Rogers    7 年前

    你可以定制 ContractResolver 那是你的 DataType 属性,并将值映射到相应的转换器。以下是您需要的代码:

    public class DataTypeResolver : DefaultContractResolver
    {
        private Dictionary<DataType, JsonConverter> ConvertersByDataType { get; set; }
    
        public DataTypeResolver()
        {
            // Adjust this list to match your actual data types and converters
            ConvertersByDataType = new Dictionary<DataType, JsonConverter>
            {
                { DataType.PostalCode, new PostalCodeConverter() },
                { DataType.PhoneNumber, new PhoneNumberConverter() },
            };
        }
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty prop = base.CreateProperty(member, memberSerialization);
            var att = prop.AttributeProvider.GetAttributes(true).OfType<DataTypeAttribute>().FirstOrDefault();
            if (att != null)
            {
                JsonConverter converter;
                if (ConvertersByDataType.TryGetValue(att.DataType, out converter))
                {
                    prop.Converter = converter;
                }
            }
            return prop;
        }
    }
    

    然后将解析器传递给 SerializeObject 和/或 DeserializeObject

    var settings = new JsonSerializerSettings
    {
        ContractResolver = new DataTypeResolver()
    };
    string json = JsonConvert.SerializeObject(yourObject, settings);
    

    https://dotnetfiddle.net/k1kWv5

        2
  •  0
  •   Markus Dresch    7 年前

    您可以将转换器添加到JsonSerializerSettings。因此,与其装饰一切,不如在那里添加邮政编码JSONConverter(取决于使用频率,装饰器可能更好):

    对于aspnet核心默认值:

    services.AddMvc().AddJsonOptions(o => o.SerializerSettings.Converters.Add(new PostcodeJsonConverter()))

    对于JsonConvert:

    JsonConvert.SerializeObject(obj, new JsonSerializerSettings
    {
        Converters = { new PostcodeJsonConverter() }
    });