Add a custom attribute to json.net

后端 未结 3 1844
温柔的废话
温柔的废话 2021-01-02 10:38

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

I want to create some custom ones that get run when the seria

3条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-02 11:01

    Since your goal is to ignore a property on serialization but not deserialization, you can use a ContractResolver.

    Note that the following class does just that, and is based on CamelCasePropertyNamesContractResolver, to make sure it serializes to camel-cased Json fields. If you don't want that, you can make it inherit from DefaultContractResolver instead.

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

    public class CamelCaseIgnoringPropertyJsonResolver : CamelCasePropertyNamesContractResolver
    {        
        protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            // list the properties to ignore
            var propertiesToIgnore =  type.GetProperties()
                    .Where(x => x.GetCustomAttributes().OfType().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()
            };
    
            var json = JsonConvert.SerializeObject(myObject, settings);
            return json;
        }
    

    Finally, the custom attribute can be of any type, but to match the example:

    internal class JsonIgnoreSerializeAttribute : Attribute
    {
    }
    

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

提交回复
热议问题