2008-11-03 64 views
5

在.NET 2.0(C#)中有沒有像使用XmlSerializer那樣以簡單/可定製的人類可讀格式(例如看起來像PXLS或JSON)序列化對象的方法? 另外我知道XML是人類可讀的,我正在尋找一些冗餘度較低的東西,這些東西可以作爲用戶輸出到控制檯的結果。以人類可讀的文本格式序列化

回答

6

序列化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藏漢...

+0

幾分鐘前,通過使用[Json.NET](http://www.codeplex.com/Json),我發現JSON不是最好的方法,因爲它不支持Enums。結果是一個不太人性化的數字。 – Martin 2008-11-03 15:10:34

+0

Okej,實現一切都取決於你正在序列化..如果它只有一個類型與少數成員,爲什麼不重寫「ToString」並返回一個字符串.Format任何格式,你想 – ullmark 2008-11-03 15:31:55

1

.Net的內置序列化選項是Xml,Xml-Soap和二進制。既然你排除了xml,二進制文件絕對不是人類可讀的,你必須自己推出。

當滾動您自己,您有幾種選擇:

  • 添加實用程序或Extention方法的類,像AviewAnew建議
  • 擴展System.Runtime.Serialization.Formatter /實施System.Runtime。 Serialization.Formatter
  • 通過谷歌在線尋找一個通用組件,它可以做你想做的事。

請注意,第二項可以專門爲您的特定類(它不必處理任何類,如果你不想要它)和後兩項不相互排斥。

我在過去搜索過一個.Net JSON格式化程序,並且在那裏肯定有多個選項。然而,我最終走向了另一個不同的方向。我對他們中的任何一個都不感到自信。也許別人可以提供更具體的建議。 JSON正在變得足夠大,希望微軟很快就能在框架中包含對它的「原生」支持。

+0

我可以寫我自己的HumanSerializer是反映被給了它該對象的類型 - 但這會耗費了太多的時間。我認爲之前可能有人解決了這個問題 - 但谷歌沒有找到他或她。 – Martin 2008-11-03 14:59:08

4

我發現了一個exaustive文檔瀏覽:

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

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

您可以使用以下標準方法獲取格式化的Json

JsonReaderWriterFactory。CreateJsonWriter(流流,編碼編碼,布爾ownsStream,布爾縮進,串indentChars)

只有設置「縮進==真」

嘗試是這樣的

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

謝謝!

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> 
相關問題