创建预定义的JsonConvert属性?

时间:2014-10-01 13:22:06

标签: c# properties json.net converter customization

我的问题很简单.. 我想做的是:

[JsonConverter(typeof(MyConverter)]
object SomeProperty {get;set;}

但是能够将其作为自定义属性编写,因此我可以使用预定义的JsonConverter属性来装饰我的属性..例如

[MyCustomConverter]
object SomeProperty {get;set;}

在这种情况下会被视为[JsonConverter(typeof(MyConverter))]

有什么想法吗?

BR, INX

2 个答案:

答案 0 :(得分:1)

这并非易事,但如果您实施一个考虑了您的属性的自定义IContractResolver,则可以执行此操作。

执行此操作涉及以下几个步骤:

  1. 为扩展abstract的属性创建System.Attribute基类:

    public abstract class ConverterAttribute : Attribute
    {
        public abstract JsonConverter Converter { get; }
    }
    
  2. 接下来,您需要创建实际使用您的属性 1 IContractResolver

    public class CustomAttributeContractResolver : DefaultContractResolver
    {   
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            JsonObjectContract contract =
                base.CreateObjectContract(objectType);
    
            IEnumerable<JsonProperty> withoutConverter =
                contract.Properties.Where(
                    pr => pr.MemberConverter == null && 
                    pr.Converter == null);
    
            // Go over the results of calling the default implementation.
            // check properties without converters for your custom attribute
            // and pull the custom converter out of that attribute.
            foreach (JsonProperty property in withoutConverter)
            {
                PropertyInfo info = 
                    objectType.GetProperty(property.UnderlyingName);
    
                var converterAttribute =
                    info.GetCustomAttribute<ConverterAttribute>();
    
                if (converterAttribute != null)
                {
                    property.Converter = converterAttribute.Converter;
                    property.MemberConverter = converterAttribute.Converter;
                }
            }
    
            return contract;
        }
    }
    
  3. 创建覆盖ConverterAttribute.Converter的属性,返回自定义转换器:

    public class MyCustomConverterAttribute : ConverterAttribute
    {
        get { return new MyCustomConverter(); }
    }
    
  4. 使用以下属性装饰您的类:

    public class MyClass
    {
        [MyCustomConverter]
        public object MyProperty { get; set; }
    }
    
  5. 在序列化或反序列化时,请在您使用的JsonSerializerSettings中指定合约解析程序:

    var settings = new JsonSerializerSettings();
    settings.ContractResolver = new CustomAttributeContractResolver();
    
    string serialized = JsonConverter.SerializeObject(new MyClass());
    
  6. 我会说这可能不值得小小的好处 - 所有你真正要做的就是保存一些字符,除非你的属性做其他事情。


    1 :我不确定MemberConverterConverter之间的区别。 序列化时,只需要Converter属性,但需要反序列化MemberConverter。我会继续挖掘,但希望有人可以提供一些见解。看起来像others have had this same question as well

答案 1 :(得分:0)

似乎不可能。 JsonConverterAttributeTypeConverterAttribute类都是密封的,这些是Json.NET用来提供自定义类型转换器的类。