2014-10-01 32 views
2

我的问题很简单.. 我想这样做是这样的:创建预定义的JsonConvert属性?

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

但可以把它写成一个自定义属性,所以我根本就装饰我用一个预先定义的JsonConverter特性属性..所以例如

[MyCustomConverter] 
object SomeProperty {get;set;} 

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

任何想法?

BR, INX

回答

0

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

1

这不是微不足道的,但如果您实现了一个将您的属性考虑在内的自定义IContractResolver,则可以执行此操作。

有涉及这样几个步骤:

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

    public abstract class ConverterAttribute : Attribute 
    { 
        public abstract JsonConverter Converter { get; } 
    } 
    
  2. 接下来,你需要创建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. 创建overrrides 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()); 
    

我想说这可能是不值得的小好处 - 所有你真的在做的是保存几个字符,除非你的属性做别的。


:我不知道什么MemberConverterConverter之间的差异。当序列化时,只需要Converter属性,但需要反序列化MemberConverter。我会继续挖掘,但希望有人能提供一些见解。看起来像others have had this same question as well

+0

嗨! 即使我用[MyCustomConverter]装饰我的财产,它的接缝。CustomAttributeContractResolver中的withoutConverter对象仍然会拾取装饰的属性。 – Inx51 2014-10-02 08:18:24

+0

它应该是--'convertConverter'包含没有'JsonConverter'属性的属性。它应该拿起属性,然后使用属性的底层'Converter'。 – 2014-10-02 13:13:12

相关问题