Избегайте использования атрибута JsonIgnore в модели домена

У меня есть компонент модели домена с несколькими классами сущностей. В другом компоненте у меня есть репозитории объектов, реализованные с использованием сериализации Json.NET. Я хочу игнорировать некоторые свойства сущности во время сериализации, поэтому прямым решением было бы украсить эти свойства атрибутом JsonIgnore. Однако, из принципа, я хотел бы избежать ссылок на другие компоненты, включая сторонние библиотеки, такие как Json.NET, в моей модели домена.

Я знаю, что я могу создать собственный распознаватель контрактов, как описано here, но сложно обобщить, что сериализовать и что не сериализуется в разных объектах, Обычно я хочу игнорировать все свойства readonly, но есть исключения, например, коллекции:

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

Я также могу создать выделенный распознаватель контрактов для каждого объекта, как описано здесь, но это похоже на решение с высоким уровнем обслуживания, особенно с многочисленными объектами.

Идеальное решение было бы, если бы Json.NET поддерживал некоторый атрибут в рамках .NET Framework, но я даже не могу найти подходящего кандидата...

Я подумал о создании собственного пользовательского атрибута Ignore в моей модели домена и создании настраиваемого адаптера контракта, который использует отражение для обнаружения этого атрибута и игнорирует декорированные свойства при сериализации. Но действительно ли это лучшее решение данной проблемы?

Ответ 1

По-моему, по умолчанию Json.net уважает DataContractAttribute. Хотя вы должны быть инклюзивными, а не эксклюзивными, это также означает, что сериализация может измениться на двоичную систему Microsoft (или, может быть, xml) и не придется переделывать ваши модели домена.

Если класс имеет много свойств, и вы хотите только сериализовать небольшое подмножество, то добавление JsonIgnore ко всем остальным будет утомительным и подверженным ошибкам. Способ решения этого сценария состоит в том, чтобы добавить DataContractAttribute к классу и DataMemberAttributes к свойствам для сериализации. Это выборочная сериализация, только те свойства, которые вы помечаете, должны быть сериализованы по сравнению с отключением сериализации с использованием 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; }
}

Ответ 2

Возможно, вы захотите использовать что-то вроде View Model для контроля того, какие свойства модели вашего объекта сериализованы. Я не использовал его сам, но изучил его использование для моего проекта, но AutoMapper может быть чем-то, что можно было бы отделить модель сущности из вашей сериализованной модели.

Ответ 3

Сериализатор Json также поддерживает селектирование выбора

[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; }
}