It's not trivial, but you can do this if you implement a custom IContractResolver that takes your attributes into account.
There are several steps involved in doing this:
Create an abstract base class for your attributes that extends System.Attribute:
public abstract class ConverterAttribute : Attribute { public abstract JsonConverter Converter { get; } }
Next, you need to create the IContractResolver that will actually use your attribute1:
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; } }
Create the attribute that overrrides ConverterAttribute.Converter, returning your custom converter:
public class MyCustomConverterAttribute : ConverterAttribute { get { return new MyCustomConverter(); } }
Decorate your class with the attribute:
public class MyClass { [MyCustomConverter] public object MyProperty { get; set; } }
When serializing or deserializing, specify the contract resolver in the JsonSerializerSettings you use:
var settings = new JsonSerializerSettings(); settings.ContractResolver = new CustomAttributeContractResolver(); string serialized = JsonConverter.SerializeObject(new MyClass());
I'd say that this probably isn't worth the small benefit--all you're really doing is saving a few characters, unless your attribute does something else.
1: I'm not sure what the difference between MemberConverter and Converter. When serializing, only the Converter property was needed, but deserializing required MemberConverter. I'll keep digging, but hopefully someone can provide some insight. Looks like others have had this same question as well.