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

发布于 2024-07-08 11:18:06 字数 216 浏览 5 评论 0 原文

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

Is there a way in .NET 2.0 (C#) to serialize object like you do using XmlSerializer in a simple / customizable human readable format thats for instance looks like PXLS or JSON?
Also I know that XML is human readable, I'm looking for something with less annoying redundancy, something that you can output to the console as a result for the user.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

尐籹人 2024-07-15 11:18:06

要在 .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 也有一个同样简单的版本......

To Serialize into JSON in .NET you do as follows:

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

The collections item need to have the "DataContract" attribute, and each member you wish to be serialized into the JSON must have the "DataMember" attibute.

It's possible that this only works for .NET 3.5. But there is an equally simple version for 2.0 aswell...

月野兔 2024-07-15 11:18:06

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

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

I found a exaustive documentation here:

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

with this usefull class (support generics)

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;
  }
}
北笙凉宸 2024-07-15 11:18:06

.Net 的内置序列化选项有 Xml、Xml-Soap 和二进制。 由于您已经排除了 xml 和二进制文件绝对不是人类可读的可能性,因此您必须自己推出。

当您自己开发时,您有几个选择:

  • 将实用程序或扩展方法添加到类中,例如 AviewAnew 建议的
  • 扩展 System.Runtime.Serialization.Formatter / 实现 System.Runtime.Serialization.IFormatter
  • 通过 google 在线查找通用组件即可你想要什么。

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

我过去曾搜索过 .Net JSON 格式化程序,并且肯定有多种选择。 然而,那一次我最终走向了不同的方向。 我只是对他们中的任何一个都不太有信心。 也许其他人可以提供更具体的建议。 JSON 已经变得足够大,希望微软很快能够在框架中包含对它的“本机”支持。

The built-in serialization options for .Net are Xml, Xml-Soap, and binary. Since you've ruled out xml and binary is definitely not human readable, you'll have to roll your own.

When rolling your own, you have a few options:

  • Add Utility or Extention methods to the class, like AviewAnew suggested
  • Extend System.Runtime.Serialization.Formatter / Implement System.Runtime.Serialization.IFormatter
  • Find a generic component online via google that will do what you want.

Note that the 2nd item can be specialized for your specific class (it doesn't have to be able to handle any class, if you don't want it to) and the latter two items are not mutually exclusive.

I have searched for a .Net JSON formatter in the past, and there are definitely multiple options out there. However, I ended up going a different direction that time. I just didn't feel very confident in any of them. Maybe someone else can provide a more specific recommendation. JSON is becoming big enough that hopefully Microsoft will include "native" support for it in the framework soon.

人心善变 2024-07-15 11:18:06

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

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

JsonReaderWriterFactory.CreateJsonWriter(Streamstream, Encodingencoding, 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 以避免在具有不同区域设置的计算机上反序列化期间出现异常。 例如,doubleDateTime 的无效格式有时会导致这些问题。

用于反序列化

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

谢谢!

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

You may use following standard method for getting formatted Json

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

Only set "indent==true"

Try something like this

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

Pay your attention to lines

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

You should use InvariantCulture to avoid exception during deserialization on the computers with different Regional settings. For example, invalid format of double or DateTime sometimes cause them.

For deserializing

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

Thanks!

三人与歌 2024-07-15 11:18:06

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

Apply a xsl to your xml to strip out what you don't want to see ?

something like

<?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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文