Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JSON.net, how do I prevent serializing properties of a derived class, when used in a base class context?

Given a data model:

[DataContract] public class Parent {     [DataMember]     public IEnumerable<ChildId> Children { get; set; } }  [DataContract] public class ChildId {     [DataMember]     public string Id { get; set; } }  [DataContract] public class ChildDetail : ChildId {     [DataMember]     public string Name { get; set; } } 

For implementation convenience reasons, there are times when the ChildId objects on the Parent are in fact ChildDetail objects. When I use JSON.net to serialize the Parent, they are written out with all of the ChildDetail properties.

Is there any way to instruct JSON.net (or any other JSON serializer, I'm not far enough into the project to be committed to one) to ignore derived class properties when serializing as a base class?

EDIT: It is important that when I serialize the derived class directly that I'm able to produce all the properties. I only want to inhibit the polymorphism in the Parent object.

like image 583
Christopher Currie Avatar asked May 03 '11 16:05

Christopher Currie


1 Answers

I use a custom Contract Resolver to limit which of my properties to serialize. This might point you in the right direction.

e.g.

/// <summary> /// json.net serializes ALL properties of a class by default /// this class will tell json.net to only serialize properties if they MATCH  /// the list of valid columns passed through the querystring to criteria object /// </summary> public class CriteriaContractResolver<T> : DefaultContractResolver {     List<string> _properties;      public CriteriaContractResolver(List<string> properties)     {         _properties = properties     }      protected override IList<JsonProperty> CreateProperties(         JsonObjectContract contract)     {         IList<JsonProperty> filtered = new List<JsonProperty>();          foreach (JsonProperty p in base.CreateProperties(contract))             if(_properties.Contains(p.PropertyName))                  filtered.Add(p);          return filtered;     } } 

In the override IList function, you could use reflection to populate the list with only the parent properties perhaps.

Contract resolver is applied to your json.net serializer. This example is from an asp.net mvc app.

JsonNetResult result = new JsonNetResult(); result.Formatting = Formatting.Indented; result.SerializerSettings.ContractResolver =      new CriteriaContractResolver<T>(Criteria); 
like image 151
Jason Watts Avatar answered Sep 20 '22 23:09

Jason Watts