JSON.NET - исключить свойства определенного типа во время выполнения - PullRequest
7 голосов
/ 27 мая 2011

Мне интересно как исключить / удалить определенные свойства заданного типа (типов) (или их наборов) из сериализации с использованием библиотеки Json.NET?Я безуспешно пытался написать свой собственный обработчик контрактов (унаследованный от DefaultContractResolver ).

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

Это выглядит довольно простой задачей, но, к сожалению, я нигде не смог найти достойного решения ...

Кстати - Я не связан с библиотекой Json.NET - если это легко сделать с помощью стандартных / других сериализаторов .NET JSON, это было бы для меня не менее хорошим решением.

ОБНОВЛЕНИЕ

Свойства должны быть исключены перед попыткой их сериализации. Почему?

Как правило, типы объектов, которые я получаю и сериализирую, могут иметь динамические свойства типа, наследуемого от IDynamicMetaObjectProvider .Я не буду описывать все детали, но DynamicMetaObject , возвращенный из GetMetaObject метод этих объектов не имеет DynamicMetaObject.GetDynamicMemberNames метод реализован (бросает NotImplementedException ...). Подводя итог - проблема в том, что эти объекты (я должен исключить) не позволяют перечислять их свойства , что сериализатор Json.NET пытается сделать за кулисами.Я всегда получаю NotImplementedException брошенным.

Ответы [ 3 ]

5 голосов
/ 27 мая 2011

Я пробовал как сериализацию JSON WCF, так и System.Web.Script.Serialization.JavaScriptSerializer .Я обнаружил, что если вы хотите полностью контролировать процесс сериализации и не хотите связываться с атрибутами и хакерами, чтобы все заработало, JavaScriptSerializer - это путь.Он включен в стек .NET и позволяет создавать и регистрировать JavaScriptConverter подклассы для выполнения настраиваемой сериализации типов.

Единственное обнаруженное мной ограничение, которое может вызвать проблемы, состоит в том, что вы не можете легко зарегистрироватьсяконвертер для преобразования всех подклассов Object (иначе говоря, один конвертер, чтобы управлять ими всеми).Вам действительно необходимо знать общие базовые классы или предварительно зарегистрировать набор типов путем сканирования сборки.Однако сериализация свойств полностью остается за вами, так что вы можете решить, используя простое отражение, какие свойства сериализовать и как.

Кроме того, сериализация по умолчанию намного лучше для JSON, чем подход WCF.По умолчанию все типы сериализуются без атрибутов, перечисления сериализуются по имени, словари строковых ключей сериализуются как объекты JSON, списки сериализуются как массивы и т. Д. Но по очевидным причинам, таким как круговые деревья, даже поведение по умолчанию время от времени нуждается в помощи.время.

В моем случае я поддерживал клиентский API, который не в точности соответствовал структуре класса сервера, и мы хотели гораздо более простой синтаксис JSON, который был бы прост для глаз, и JavaScriptSerializer сделалтрюк каждый раз.Просто дайте мне знать, если вам нужны примеры кода для начала работы.

2 голосов
/ 27 мая 2011

Создайте свой собственный обработчик контрактов, переопределите метод, который создает свойства для объекта, а затем отфильтруйте результаты, чтобы включить только те, которые вы хотите.

0 голосов
/ 29 июня 2012

Рассматривали ли вы возможность использования свойства префикса ShouldSerialize для исключения свойства вашего определенного типа во время выполнения?

public class Employee
{
  public string Name { get; set; }
  public Employee Manager { get; set; }

  public bool ShouldSerializeManager()
  {
    return (Manager != this);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...