Какая сериализация .NET-объектов является наиболее гибкой, но простой в реализации?

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

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

That means that Binary Serialization is not an option as it only works with the other .NET Platforms. I would also like something readable by a person, and thus decipherable by a management program and other interpreters.

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
0
7 300
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

Не был уверен, хотел ли mrbradleyt игнорировать некоторые части графа классов, когда он сказал, что не хочет об этом беспокоиться. В этом случае не все атрибуты должны быть сериализуемыми (NonSerializedAttribute может отмечать поля, которые следует исключить)

Hamish Smith 20.09.2008 04:51

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

Ben Hoffstein 20.09.2008 04:54

Спрашивающий специально исключил двоичную сериализацию.

Andrei Rînea 20.09.2008 13:58

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

В частности, вы можете найти все сообщения Шона, относящиеся к промежуточному сериализатору, здесь: talula.demon.co.uk/blogindex.html#intermediateserializer

Joel Martinez 01.06.2009 22:15

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

Я считаю, что использование сериализации SOAP не рекомендуется в NET 2.0. На самом деле он даже не обрабатывает дженерики. social.msdn.microsoft.com/Forums/en-US/netfxremoting/thread/‌…

Santiago Palladino 20.09.2008 06:33

Где-то в Serialization.Formatters.oap

ripper234 20.09.2008 07:55

Судя по вашим требованиям, лучше всего подходит сериализация Xml.

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

Не могли бы вы подробнее рассказать об атрибуте XmlArray ... У меня были проблемы со списками ....

mrbradleyt 20.09.2008 05:06

Атрибут XmlArray на самом деле не нужен, если вы используете sgen. Общий шаблон состоит в том, чтобы получить отдельный класс от List <YourObject>, а затем сериализовать его, например. [Serializable] открытый класс YourObjectCollection: List <YourObject> {} Однако я обнаружил, что даже в этом нет необходимости

ilitirit 20.09.2008 06:44

+1 милитирит. Исправлена ​​раздражающая проблема, с которой я не мог сериализовать список, не получив дополнительный набор тегов, обертывающих его, поэтому я не мог ReadXml его в DataSet.

Jared Updike 20.12.2008 02:27

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

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

[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

Сообщите мне, если это сработает для вас.

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

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

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

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

Возможно, более эффективным способом будет сериализация с использованием BinaryFormatter.

Как скопировано из http://blog.paranoidferret.com/index.php/2007/04/27/csharp-tutorial-serialize-objects-to-a-file/

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class Serializer
{
   public Serializer()
   {
   }

   public void SerializeObject(string filename,
                  ObjectToSerialize objectToSerialize)
   {
      Stream stream = File.Open(filename, FileMode.Create);
      BinaryFormatter bFormatter = new BinaryFormatter();
      bFormatter.Serialize(stream, objectToSerialize);
      stream.Close();
   }

   public ObjectToSerialize DeSerializeObject(string filename)
   {
      ObjectToSerialize objectToSerialize;
      Stream stream = File.Open(filename, FileMode.Open);
      BinaryFormatter bFormatter = new BinaryFormatter();
      objectToSerialize =
         (ObjectToSerialize)bFormatter.Deserialize(stream);
      stream.Close();
      return objectToSerialize;
   }
}
Ответ принят как подходящий

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

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

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

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

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

Я пробовал это, и это дало мне лучшие результаты ошибок, чем стандартный сериализатор DataManinpulator JSON, однако он все равно провалился из-за циклической ссылки. Какие-нибудь советы? Я создаю платформу обмена сообщениями и не могу контролировать фактическую структуру любого объекта.

mrbradleyt 20.09.2008 08:14

Задайте для свойства ReferenceLoopHandling JsonSerializer значение Ignore.

James Newton-King 20.09.2008 09:15

Это также очень удобно для отладки, если вы когда-нибудь захотите выгрузить объект в файл журнала или на консоль. Отличный инструмент.

aboy021 22.03.2013 09:24

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

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

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

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

Я согласен с тем, что методы сериализации на основе 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), что он не уверен, почему, и что он должен поддерживаться немного дольше.

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

Похожие вопросы

Как мне вставить USB-накопитель и удалить события в сервисе, не слыша, как к моему жесткому диску постоянно обращаются на некоторых операционных системах?
Требование от пользователей обновить .NET
Как указать путь к сборке в GAC в записях реестра, добавленных пакетом установщика Windows?
Доступ к изображению в ресурсах проекта?
C# - Можно ли скрыть общедоступные унаследованные методы (например, сделать их закрытыми для производного класса)
Получение нескольких потоков пользовательского интерфейса в Windows Forms
Как программно определить количество ссылок на метод с помощью C#
Есть ли случай, когда синтаксис делегата предпочтительнее лямбда-выражения для анонимных методов?
Как создать AxHost исключительно в коде [C#]
Как мне уступить потоку пользовательского интерфейса для обновления пользовательского интерфейса при выполнении пакетной обработки в приложении WinForm?