Сериализация в удобочитаемом текстовом формате - PullRequest
5 голосов
/ 03 ноября 2008

Есть ли в .NET 2.0 (C #) способ сериализации объекта, как вы делаете это с помощью XmlSerializer в простом / настраиваемом удобочитаемом для человека формате, который, например, выглядит как PXLS или JSON? Также я знаю, что XML удобен для чтения человеком, я ищу что-то с меньшей раздражающей избыточностью, что-то, что вы можете вывести на консоль в результате для пользователя.

Ответы [ 5 ]

6 голосов
/ 03 ноября 2008

Для сериализации в JSON в .NET вы должны сделать следующее:

public static string ToJson(IEnumerable collection)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(collection.GetType());
            string json;
            using (MemoryStream m = new MemoryStream())
            {
                XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(m);
                ser.WriteObject(m, collection);
                writer.Flush();

                json = Encoding.Default.GetString(m.ToArray());
            }
            return json;
        }

Элемент коллекций должен иметь атрибут «DataContract», а каждый член, который вы хотите сериализовать в JSON, должен иметь атрибут «DataMember».

Возможно, это работает только для .NET 3.5. Но есть не менее простая версия для 2.0, а также ...

4 голосов
/ 31 марта 2010

Я нашел здесь исчерпывающую документацию:

http://pietschsoft.com/post/2008/02/NET-35-JSON-Serialization-using-the-DataContractJsonSerializer.aspx

с этим полезным классом (поддержка обобщений)

using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

public class JSONHelper
{
  public static string Serialize<T>(T obj)
  {
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
      MemoryStream ms = new MemoryStream();
      serializer.WriteObject(ms, obj);
      string retVal = Encoding.Default.GetString(ms.ToArray());
      ms.Dispose();
      return retVal;
  }

  public static T Deserialize<T>(string json)
  {
      T obj = Activator.CreateInstance<T>();
      MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
      obj = (T)serializer.ReadObject(ms);
      ms.Close();
      ms.Dispose();
      return obj;
  }
}
1 голос
/ 23 июля 2016

https://stackoverflow.com/a/38538454/6627992

Вы можете использовать следующий стандартный метод для получения отформатированного Json

JsonReaderWriterFactory.CreateJsonWriter (Поток потока, кодировка кодирования, bool ownsStream, отступ bool, строка indentChars)

Только установить "отступ == true"

Попробуйте что-то вроде этого

    public readonly DataContractJsonSerializerSettings Settings = 
            new DataContractJsonSerializerSettings
            { UseSimpleDictionaryFormat = true };

    public void Keep<TValue>(TValue item, string path)
    {
        try
        {
            using (var stream = File.Open(path, FileMode.Create))
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture;
                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                        stream, Encoding.UTF8, true, true, "  "))
                    {
                        var serializer = new DataContractJsonSerializer(type, Settings);
                        serializer.WriteObject(writer, item);
                        writer.Flush();
                    }
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                }
                finally
                {
                    Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.ToString());
        }
    }

Обратите внимание на строки

    var currentCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    ....
    Thread.CurrentThread.CurrentCulture = currentCulture;

Вам следует использовать InvariantCulture , чтобы избежать исключений при десериализации на компьютерах с различными региональными настройками. Например, неправильный формат double или DateTime иногда вызывает их.

для десериализации

    public TValue Revive<TValue>(string path, params object[] constructorArgs)
    {
        try
        {
            using (var stream = File.OpenRead(path))
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture;
                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    var serializer = new DataContractJsonSerializer(type, Settings);
                    var item = (TValue) serializer.ReadObject(stream);
                    if (Equals(item, null)) throw new Exception();
                    return item;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                    return (TValue) Activator.CreateInstance(type, constructorArgs);
                }
                finally
                {
                    Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch
        {
            return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
        }
    }

Спасибо!

1 голос
/ 03 ноября 2008

Встроенными вариантами сериализации для .Net являются Xml, Xml-Soap и двоичный файл. Поскольку вы исключили xml, а бинарный файл определенно не читается человеком, вам придется свернуть свой собственный.

Прикатывая свои, у вас есть несколько вариантов:

  • Добавить в класс методы Utility или Extention, как предложил AviewAnew
  • Расширение System.Runtime.Serialization.Formatter / Реализация System.Runtime.Serialization.IFormatter
  • Найдите общий компонент онлайн через Google, который будет делать то, что вы хотите.

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

В прошлом я искал форматер .Net JSON, и определенно существует несколько вариантов. Однако в этот раз я пошел в другом направлении. Я просто не чувствовал себя очень уверенно ни в одном из них. Может быть, кто-то еще может дать более конкретную рекомендацию. JSON становится достаточно большим, и мы надеемся, что в скором времени Microsoft включит в него «нативную» поддержку.

0 голосов
/ 21 февраля 2017

Применить xsl к вашему xml, чтобы удалить то, что вы не хотите видеть?

что-то вроде

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
  <xsl:template match="*">
      <xsl:value-of select="name()" /><xsl:text>
</xsl:text>
      <xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
  </xsl:template>
  <xsl:template match="@*|text()|comment()|processing-instruction">
   <xsl:value-of select="name()" />:<xsl:value-of select="." /><xsl:text>
</xsl:text>
  </xsl:template>
</xsl:stylesheet>
...