Newtonsoft игнорирует атрибуты?
В настоящее время я использую те же D # CTO для извлечения данных из CouchDB через LoveSeat, который я собираюсь вернуть JSON через контроллер ASP MVC.
Я использую библиотеку NewtonSoft, чтобы изолировать мои DTO перед отправкой их через контроллер.
Однако, поскольку CouchDB также использует NewtonSoft, он также учитывает атрибуты уровня свойств NewtonSoft, такие как
[JsonIgnore]
[JsonProperty("foo")]
Можно ли как-то сказать библиотеке newtonsoft, чтобы они явно игнорировали эти атрибуты? LoveSeat позволяет мне предоставить собственную реализацию IObjectSerializer, которая дает мне полный контроль над сетью JsonSerializerSettings. Итак, могу ли я игнорировать атрибуты с помощью этих настроек?
Я спрашиваю, поскольку единственная альтернатива, которую я могу видеть в этом пункте, состоит в том, чтобы обмануть мои DTO. Хотя это не так уж и ужасно, но и не здорово.
Единственный другой способ, который я могу увидеть, - это ввести в свой проект мою собственную версию исходного кода Newtonsoft.Json, с другим названием сборки и т.д. И т.д. Но этот способ безумие определенно лжет, и я просто обману DTO, прежде чем перейти к этому. Дорога.
Ответы
Ответ 1
Я закончил создание всех свойств, необходимых мне только для добавления атрибутов к виртуальным и переопределения их в одном классе с соответствующими атрибутами newtonsoft.
Это позволяет мне иметь различное поведение при сериализации при де-сериализации из CouchDB и сериализации для GET без лишних ошибок. Это прекрасно, и бонус, что эти два связаны; любые изменения в базе я бы хотел все равно.
Было бы неплохо узнать, возможен ли мой первоначальный вопрос?
Ответ 2
Я не уверен, что это то, что вам нужно, но из того, что я понимаю, вы ищете атрибут [JsonIgnore]
. Остановка свойств из сериализации с остальной частью объекта в JSON.
[JsonIgnore]
public string Whatever{ get; set; }
Ответ 3
Одно предложение, которое вам может не понравиться. Для наилучшей практики я рекомендую иметь два почти одинаковых объекта. Один специально для вашего уровня доступа к данным (объект домена), который сопоставляется с вашей БД. И отдельный DTO, о котором заботятся ваши приложения. Таким образом, объект домена будет содержать больше свойств, чем DTO, и вы можете отделить проблемы.
Ответ 4
Согласно документации Json.NET
Вы можете добавить метод в свой класс: public bool ShouldSerialize_________(){...}
и заполнить пробел названием свойства, которое вы не хотите сериализовать. Если метод возвращает false
, свойство будет проигнорировано.
Пример из документации не хочет сериализовать менеджера сотрудника, если менеджер - тот же сотрудник.
public class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }
public bool ShouldSerializeManager()
{
// don't serialize the Manager property if an employee is their own manager
return (Manager != this);
}
}
Вы можете установить для своего класса какое-то запрещающее действие:
public class DTO
{
[JsonIgnore]
public bool IsWritingToDatabase { get; set; }
public string AlwaysSerialize { get; set; }
public string Optional { get; set; }
public bool ShouldSerializeOptional()
{
return IsWritingToDatabase;
}
}
Но это не намного проще, чем иметь два объекта. Поэтому я бы рекомендовал делать так, как говорит @zbugs, и иметь отдельные определения для стороны API и стороны DB.
Ответ 5
Эта ссылка newtonking.com помогла в аналогичной ситуации. Он расширяет класс DefaultContractResolver
. Чтобы заставить его работать, мне пришлось заменить
protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
с
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)