Avoid using the JsonIgnore attribute in a domain model
Asked Answered
T

3

11

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?

Townie answered 25/3, 2014 at 15:14 Comment(0)
A
11

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; }
}
Altostratus answered 25/3, 2014 at 16:27 Comment(0)
N
2

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.

Necrophilism answered 3/8, 2016 at 9:31 Comment(1)
I like this because it's built into the library. It's also good that it skips inherited properties.Rhodolite
Y
0

You might consider using something like a View Model to control which properties of your entity model are serialized. I haven't used it myself, but looked into using it for a project of mine, but AutoMapper might be something to look into to decouple the entity model from your serialized model.

Yung answered 25/3, 2014 at 15:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.