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

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

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

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

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

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

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

3 ответа

Решение

По умолчанию я считаю, что 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; }
}

Сериализатор 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; }
}

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

Другие вопросы по тегам