Какая сериализация является наиболее гибкой для .СЕТЕВЫХ объектов, но простой в реализации?

StackOverflow https://stackoverflow.com/questions/106599

Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

[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

Дай мне знать, если у тебя это получится.

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

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

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

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

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

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

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

http://msdn.microsoft.com/en-us/library/bk3w6240 (ПРОТИВ 80).aspx

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

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

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

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

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

Возможно, более эффективным способом была бы сериализация с использованием 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;
   }
}

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top