Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid using the JsonIgnore attribute in a domain model

Tags:

c#

.net

json.net

I have a domain model component with several entity classes. In another component i have entity repositories implemented using Json.NET serialization. I want to ignore some of the entity properties during serialization, so the straight forward solution would be to decorate those properties with the JsonIgnore attribute. However, out of principle, i would like to avoid references to other components - including 3rd party libraries like Json.NET - in my domain model.

I know that I can create a custom contract resolver as described here but it is hard to generalize what to serialize and what not to serialize in the various entities. Generally I want to ignore all readonly properties, but there are exceptions as for example collections:

public List<Pixel> Pixels
{
    get { return this.Pixels; }
}

I can also create a dedicated contract resolver for each entity as described here but that seems like a high-maintenance solution to me - especially with numerous entities.

The ideal solution would be if Json.NET had support for some attribute within the .NET framework, but I cannot even find an appropriate candidate...

I thought about making my own custom Ignore attribute in my domain model and making a custom contract resolver that uses reflection to detect this attribute and ignores the decorated properties when serializing. But is that really the best solution to the given problem?

like image 419
Lars Michael Avatar asked Mar 25 '14 15:03

Lars Michael


2 Answers

I believe by default that Json.net Respects the DataContractAttribute. Although you have to be inclusive instead of exclusive, it also means that the serialization can change to Microsofts Binary (or maybe xml) and not have to redesign your domain models.

If a class has many properties and you only want to serialize a small subset of them then adding JsonIgnore to all the others will be tedious and error prone. The way to tackle this scenario is to add the DataContractAttribute to the class and DataMemberAttributes to the properties to serialize. This is opt-in serialization, only the properties you mark up with be serialized, compared to opt-out serialization using JsonIgnoreAttribute.

[DataContract]
public class Computer
{
  // included in JSON
  [DataMember]
  public string Name { get; set; }
  [DataMember]
  public decimal SalePrice { get; set; }

  // ignored
  public string Manufacture { get; set; }
  public int StockCount { get; set; }
  public decimal WholeSalePrice { get; set; }
  public DateTime NextShipmentDate { get; set; }
}
like image 90
Erik Philips Avatar answered Oct 26 '22 01:10

Erik Philips


The Json serializer also supports opt-in serialization:

[JsonObject(MemberSerialization.OptIn)]
public class File
{
  // excluded from serialization
  // does not have JsonPropertyAttribute
  public Guid Id { get; set; }

  [JsonProperty]
  public string Name { get; set; }

  [JsonProperty]
  public int Size { get; set; }
}

From the Optin enum value docs:

Only members marked with JsonPropertyAttribute or DataMemberAttribute are serialized. This member serialization mode can also be set by marking the class with DataContractAttribute.

like image 22
alan Avatar answered Oct 26 '22 02:10

alan