2008-11-03 44 views
5

Có cách nào trong .NET 2.0 (C#) để tuần tự hóa đối tượng giống như bạn sử dụng XmlSerializer theo định dạng đơn giản có thể đọc được của con người chẳng hạn như PXLS hoặc JSON? Ngoài ra tôi biết rằng XML là con người có thể đọc được, tôi đang tìm một cái gì đó với dự phòng ít gây phiền nhiễu, một cái gì đó mà bạn có thể xuất ra bàn điều khiển như là kết quả cho người dùng.Sắp xếp theo định dạng văn bản có thể đọc được của con người

Trả lời

6

serialize vào JSON trong .NET bạn làm như sau:

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

Các bộ sưu tập item cần phải có "DataContract" thuộc tính, và mỗi thành viên bạn muốn được đăng vào JSON phải có " DataMember "attibute.

Có thể tính năng này chỉ hoạt động đối với .NET 3.5. Nhưng có một phiên bản đều đơn giản cho 2,0 là tốt ...

+0

Một vài phút trước bằng cách sử dụng [Json.NET] (http://www.codeplex.com/Json) Tôi phát hiện ra rằng JSON không phải là cách tốt nhất để làm điều đó vì nó không hỗ trợ Enums. Kết quả là một con số không phải là rất dễ đọc. – Martin

+0

Okej, thực hiện tốt tất cả phụ thuộc vào những gì bạn đang serializing .. Nếu nó chỉ là một loại với vài thành viên tại sao không chỉ ghi đè lên "ToString" và trả về một string.Format trong bất cứ định dạng nào bạn muốn – ullmark

1

Tùy chọn tuần tự hóa tích hợp cho .Net là Xml, Xml-Soap và nhị phân. Vì bạn đã loại trừ xml và nhị phân chắc chắn không phải là con người có thể đọc được, bạn sẽ phải cuộn của riêng bạn.

Khi cán của riêng bạn, bạn có một vài lựa chọn:

  • Thêm Utility hay Extention phương thức cho lớp, như AviewAnew gợi ý
  • Mở rộng System.Runtime.Serialization.Formatter/Thực hiện System.Runtime. Nối tiếp.IFormatter
  • Tìm một thành phần chung trực tuyến qua google sẽ thực hiện những gì bạn muốn.

Lưu ý rằng mục thứ 2 có thể chuyên cho lớp cụ thể của bạn (nó không phải xử lý bất kỳ lớp nào, nếu bạn không muốn) và hai mục sau không loại trừ lẫn nhau .

Tôi đã tìm kiếm một trình định dạng JSON .Net trong quá khứ và chắc chắn có nhiều tùy chọn ngoài đó. Tuy nhiên, cuối cùng tôi đã đi theo một hướng khác. Tôi không cảm thấy tự tin lắm. Có thể ai đó khác có thể cung cấp đề xuất cụ thể hơn. JSON đang trở nên đủ lớn, hy vọng rằng Microsoft sẽ sớm đưa hỗ trợ "nguyên gốc" vào trong khuôn khổ đó.

+0

tôi có thể viết HumanSerializer của riêng tôi mà là phản ánh các loại của đối tượng đó đã được trao cho nó - nhưng điều này sẽ tiêu tốn quá nhiều thời gian. Tôi nghĩ rằng đã có thể có một người đã giải quyết vấn đề này trước đây - nhưng google đã không tìm thấy anh ta hoặc cô ấy. – Martin

4

Tôi tìm thấy một tài liệu hướng dẫn exaustive đây:

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

với lớp hữu ích này (hỗ trợ 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; 
    } 
} 
+1

Điều gì về định dạng văn bản có thể đọc được con người ? – MajesticRa

+0

Sử dụng 'Encoding.Default' không hoạt động đối với văn bản không phải ASCII vì việc triển khai (không có giấy tờ) của' DataContractJsonSerializer.WriteObject' sử dụng mã hóa cứng 'Encoding.UTF8'. – mrexodia

2

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

Bạn có thể sử dụng phương pháp tiêu chuẩn sau để được định dạng Json

JsonReaderWriterFactory.CreateJsonWriter (dòng suối, mã hóa Encoding, bool ownsStream, bool thụt lề, chuỗi indentChars)

Chỉ thiết "thụt lề == true"

Hãy thử một cái gì đó như thế này

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

Hãy chú ý của bạn vào dòng

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

Bạn nên sử dụng Biến thể số để tránh ngoại lệ trong quá trình deserialization trên các máy tính có cài đặt Regional khác nhau. Ví dụ: định dạng không hợp lệ của đôi hoặc Ngày giờ đôi khi gây ra chúng.

Đối 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); 
     } 
    } 

Cảm ơn!

0

Áp dụng xsl vào xml của bạn để loại bỏ những gì bạn không muốn thấy?

cái gì đó như

<?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> 
Các vấn đề liên quan