以人类可读的文本格式序列化

时间:2008-11-03 14:25:02

标签: c# .net serialization .net-2.0

在.NET 2.0(C#)中是否有一种方法可以像使用XmlSerializer那样使用简单/可自定义的人类可读格式来序列化对象,例如看起来像PXLS或JSON? 另外我知道XML是人类可读的,我正在寻找一些不那么令人讨厌的冗余的东西,你可以输出到用户的控制台。

5 个答案:

答案 0 :(得分:6)

要在.NET中序列化为JSON,请执行以下操作:

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以及......

答案 1 :(得分:4)

我在这里找到了详尽的文档:

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;
  }
}

答案 2 :(得分:1)

.Net的内置序列化选项是Xml,Xml-Soap和二进制文件。既然你已经排除了xml和二进制文件绝对不是人类可读的,你就必须自己动手。

滚动自己的时候,你有几个选择:

  • 向课程中添加Utility或Extention方法,例如AviewAnew建议
  • 扩展System.Runtime.Serialization.Formatter / Implement System.Runtime.Serialization.IFormatter
  • 通过谷歌在线查找符合您要求的通用组件。

请注意,第二项可以专门用于您的特定类(如果您不希望它,则不必处理任何类),后两项不是互斥的。

我过去曾搜索过.Net JSON格式化程序,肯定有多种选择。但是,那个时候我最终走向了另一个方向。我对他们中的任何一个都没有信心。也许其他人可以提供更具体的建议。 JSON正在变得越来越大,希望微软将很快在框架中包含“原生”支持。

答案 3 :(得分:1)

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

您可以使用以下标准方法获取格式化的Json

JsonReaderWriterFactory.CreateJsonWriter(Stream stream,Encoding encoding,bool ownsStream,bool indent,string indentChars)

仅设置“indent == 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);
        }
    }

谢谢!

答案 4 :(得分:0)

将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>