Adding a custom attribute to json.net

JSON.NET comes with property attributes such as [JsonIgnore] and [JsonProperty] .

I want to create some custom ones that start when serialization starts. [JsonIgnoreSerialize] or [ JsonIgnoreDeserialize]

How can I expand the scope to include this?

+7
source share
2 answers

You can write your own custom resolver like this

 public class MyContractResolver<T> : Newtonsoft.Json.Serialization.DefaultContractResolver where T : Attribute { Type _AttributeToIgnore = null; public MyContractResolver() { _AttributeToIgnore = typeof(T); } protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var list = type.GetProperties() .Where(x => !x.GetCustomAttributes().Any(a => a.GetType() == _AttributeToIgnore)) .Select(p => new JsonProperty() { PropertyName = p.Name, PropertyType = p.PropertyType, Readable = true, Writable = true, ValueProvider = base.CreateMemberValueProvider(p) }).ToList(); return list; } } 

You can use it in serialization / deserialization, for example

 var json = JsonConvert.SerializeObject( obj, new JsonSerializerSettings() { ContractResolver = new MyContractResolver<JsonIgnoreSerialize>() }); var obj = JsonConvert.DeserializeObject<SomeType>( json, new JsonSerializerSettings() { ContractResolver = new MyContractResolver<JsonIgnoreDeserialize>() }); 
+7
source

Since your goal is to ignore the property when serializing, but not deserializing, you can use ContractResolver .

Note that the following class does just that and is based on CamelCasePropertyNamesContractResolver to make sure it is serialized in Json fields on a camel basis. If you do not want this, you can inherit it from DefaultContractResolver .

Also, the example I had is based on a string name, but you can easily check if a property is decorated with your custom attribute instead of comparing the property name.

 public class CamelCaseIgnoringPropertyJsonResolver<T> : CamelCasePropertyNamesContractResolver { protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { // list the properties to ignore var propertiesToIgnore = type.GetProperties() .Where(x => x.GetCustomAttributes().OfType<T>().Any()); // Build the properties list var properties = base.CreateProperties(type, memberSerialization); // only serialize properties that are not ignored properties = properties .Where(p => propertiesToIgnore.All(info => info.Name != p.UnderlyingName)) .ToList(); return properties; } } 

Then you can use it as follows:

  static private string SerializeMyObject(object myObject) { var settings = new JsonSerializerSettings { ContractResolver = new CamelCaseIgnoringPropertyJsonResolver<JsonIgnoreSerializeAttribute>() }; var json = JsonConvert.SerializeObject(myObject, settings); return json; } 

Finally, the user attribute can be of any type, but as per the example:

 internal class JsonIgnoreSerializeAttribute : Attribute { } 

The approach is tested, and also works with nested objects.

+2
source

Source: https://habr.com/ru/post/1232801/


All Articles