Какова наиболее гибкая сериализация для объектов .NET, но простая в реализации? - PullRequest
30 голосов
/ 20 сентября 2008

Я хотел бы сериализовать и десериализовать объекты, не беспокоясь обо всем графе классов.

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

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

Я обнаружил проблемы с использованием DataContract, JSON и XML Serializer.

  • Большинство этих ошибок, по-видимому, связаны с сериализацией списков / словарей (т. Е. XML Serializable Generic Dictionary ).
  • "Добавить любые типы, статически не известные к списку известных типов - для Например, используя Атрибут KnownTypeAttribute или добавив их в список известных типы переданы DataContractSerializer. "

Пожалуйста, основывайте свои ответы на реальном опыте, а не на теории или чтении статьи.

Ответы [ 12 ]

53 голосов
/ 20 сентября 2008

Рассматривали ли вы сериализацию в JSON вместо XML?

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

Это дает вам кучу контроля через различные опции на сериализаторе и позволяет вам переопределить, как тип сериализуется, создав для него JsonConverter.

По моему мнению, JSON более удобочитаем, чем XML, и Json.NET дает возможность писать JSON с хорошим форматированием.

Наконец, проект с открытым исходным кодом, так что вы можете перейти к коду и внести изменения, если вам нужно.

3 голосов
/ 20 сентября 2008

Если я вспомню, это работает примерно так со свойством:

[XmlArray("Foo")]
[XmlArrayItem("Bar")]
public List<BarClass> FooBars
{ get; set; }

Если вы сериализовали это, вы получите что-то вроде:

<Foo>
    <Bar />
    <Bar />
</Foo>

Конечно, я, наверное, должен обратиться к экспертам. Вот больше информации от MS: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute.aspx

Дайте мне знать, если это сработает для вас.

2 голосов
/ 20 сентября 2008

Исходя из ваших требований, звучит так, что сериализация в формате XML лучше.

Какие у вас проблемы с коллекциями при сериализации? Если вы имеете в виду, что вы не знаете, какие атрибуты использовать в списке или что-то подобное, вы можете Атрибут XmlArray в вашей собственности. Вы можете определенно сериализовать коллекцию.

1 голос
/ 20 сентября 2008

Я согласен, что методы сериализации на основе DataContract (в JSON, XML и т. Д.) Немного сложнее, чем хотелось бы.

Если вы пытаетесь получить JSON, проверьте http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Это часть расширений MS AJAX. По общему признанию это помечено как Устаревшее в .NET 3.5, но ScottGu упоминает в своем комментарии блога здесь (http://weblogs.asp.net/scottgu/archive/2007/10/01/tip-trick-building-a-tojson-extension-method-using-net-3-5.aspx#4301973), что он не уверен почему, и это должно поддерживаться немного дольше.

1 голос
/ 20 сентября 2008

Поместите все классы, которые вы хотите сериализовать, в отдельную сборку, а затем используйте инструмент sgen для генерации сборки сериализации для сериализации в XML. Используйте атрибуты XML для управления сериализацией.

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

http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

FWIW, мне удалось сериализовать всю AdsML Framework (более 400 классов), используя эту технику. Это потребовало много ручной настройки, но обойти это невозможно, если принять во внимание размер фреймворка. (Я использовал отдельный инструмент для перехода с XSD на C #)

1 голос
/ 20 сентября 2008

У вас будут проблемы с сериализацией коллекции, если объекты в коллекции содержат какие-либо ссылки на другие объекты в той же коллекции. Если существует какой-либо тип двойного наведения, вы в конечном итоге создаете мультикарту, которую нельзя сериализовать. В каждой проблеме, с которой у меня когда-либо была сериализация пользовательской коллекции, это было всегда из-за некоторой дополнительной функциональности, в которой я нуждался, которая прекрасно работала как часть «типичного» клиент-серверного приложения, а затем с треском проваливалась как часть поставщика-потребителя. приложение.

1 голос
/ 20 сентября 2008

Сериализация SOAP хорошо работает для меня, даже для объектов, не помеченных [Serializable]

1 голос
/ 20 сентября 2008

IntermediateSerializer в платформе XNA Framework чертовски крут. Вы можете найти кучу уроков по его использованию на http://blogs.msdn.com/shawnhar

0 голосов
/ 20 сентября 2008

Вы должны использовать NetDataContractSerializer. Он охватывает любой вид графов объектов и поддерживает обобщения, списки, полиморфизм (атрибут KnownType здесь не нужен), рекурсию и т. Д. Единственный недостаток заключается в том, что вы должны пометить все свои классы атрибутами [Serializable] / [DataContract], но опыт показывает, что вам все равно придется выполнять какую-то ручную подстройку, поскольку не все члены должны сохраняться. Также он сериализуется в Xml, хотя его читабельность сомнительна.

У нас были те же требования, что и у вас, и мы выбрали это решение.

0 голосов
/ 20 сентября 2008

Для совместимости мы всегда использовали сериализацию Xml и позаботились о том, чтобы наш класс был спроектирован с нуля, чтобы делать это правильно.

Мы создаем документ схемы XSD и генерируем набор классов из него с помощью XSD.exe. Это генерирует частичные классы, поэтому мы затем создаем набор соответствующих частичных классов, чтобы добавить дополнительные методы, которые мы хотим помочь нам заполнить классы и использовать их в нашем приложении (так как они ориентированы на сериализацию и десериализацию и их немного сложно использовать иногда ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...