I need to be able to control how/whether certain properties on a class are serialized. The simplest case is [ScriptIgnore]
. However, I only want these attributes to be honored for this one specific serialization situation I am working on - if other modules downstream in the application also want to serialize these objects, none of these attributes should get in the way.
So my thought is to use a custom attribute MyAttribute
on the properties, and initialize the specific instance of JsonSerializer with a hook that knows to look for that attribute.
At first glance, I don't see any of the available hook points in JSON.NET will provide the PropertyInfo
for the current property to do such an inspection - only the property's value. Am I missing something? Or a better way to approach this?
To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.
You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.
JsonSerializationException(String, Exception) Initializes a new instance of the JsonSerializationException class with a specified error message and a reference to the inner exception that is the cause of this exception.
All fields, both public and private, are serialized and properties are ignored. This can be specified by setting MemberSerialization. Fields on a type with the JsonObjectAttribute or by using the . NET SerializableAttribute and setting IgnoreSerializableAttribute on DefaultContractResolver to false.
Here's a generic reusable "ignore property" resolver based on the accepted answer:
/// <summary> /// Special JsonConvert resolver that allows you to ignore properties. See https://stackoverflow.com/a/13588192/1037948 /// </summary> public class IgnorableSerializerContractResolver : DefaultContractResolver { protected readonly Dictionary<Type, HashSet<string>> Ignores; public IgnorableSerializerContractResolver() { this.Ignores = new Dictionary<Type, HashSet<string>>(); } /// <summary> /// Explicitly ignore the given property(s) for the given type /// </summary> /// <param name="type"></param> /// <param name="propertyName">one or more properties to ignore. Leave empty to ignore the type entirely.</param> public void Ignore(Type type, params string[] propertyName) { // start bucket if DNE if (!this.Ignores.ContainsKey(type)) this.Ignores[type] = new HashSet<string>(); foreach (var prop in propertyName) { this.Ignores[type].Add(prop); } } /// <summary> /// Is the given property for the given type ignored? /// </summary> /// <param name="type"></param> /// <param name="propertyName"></param> /// <returns></returns> public bool IsIgnored(Type type, string propertyName) { if (!this.Ignores.ContainsKey(type)) return false; // if no properties provided, ignore the type entirely if (this.Ignores[type].Count == 0) return true; return this.Ignores[type].Contains(propertyName); } /// <summary> /// The decision logic goes here /// </summary> /// <param name="member"></param> /// <param name="memberSerialization"></param> /// <returns></returns> protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); if (this.IsIgnored(property.DeclaringType, property.PropertyName) // need to check basetype as well for EF -- @per comment by user576838 || this.IsIgnored(property.DeclaringType.BaseType, property.PropertyName)) { property.ShouldSerialize = instance => { return false; }; } return property; } }
And usage:
var jsonResolver = new IgnorableSerializerContractResolver(); // ignore single property jsonResolver.Ignore(typeof(Company), "WebSites"); // ignore single datatype jsonResolver.Ignore(typeof(System.Data.Objects.DataClasses.EntityObject)); var jsonSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, ContractResolver = jsonResolver };
Use the JsonIgnore
attribute.
For example, to exclude Id
:
public class Person { [JsonIgnore] public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With