2012-02-27 26 views
20

tôi có phương pháp mở rộng nàyTại sao XmlWriter luôn sử dụng mã hóa utf-16?

public static string SerializeObject<T>(this T value) 
    { 
     var serializer = new XmlSerializer(typeof(T));   
     var settings = new XmlWriterSettings 
         { 
         Encoding = new UTF8Encoding(true), 
         Indent = false, 
         OmitXmlDeclaration = false, 
         NewLineHandling = NewLineHandling.None 
         }; 

     using(var stringWriter = new StringWriter()) 
     { 
      using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) 
      { 
       serializer.Serialize(xmlWriter, value); 
      } 

      return stringWriter.ToString(); 
     } 
    } 

nhưng bất cứ khi nào tôi gọi đây là nó có một mã hóa của utf-16 quy định, tức là <?xml version="1.0" encoding="utf-16"?>. Tôi đang làm gì sai?

+0

thể trùng lặp của [Làm thế nào để đặt một thuộc tính mã hóa để xml khác mà utf-16 với XmlWriter?] (Http://stackoverflow.com/questions/427725/ làm thế nào để đặt-một-mã hóa-thuộc tính-to-xml-khác-mà-utf-16-với-xmlwriter) –

+0

Tôi đã nhận ra rằng đây là một dupe, do đó, bỏ phiếu để đóng –

Trả lời

10

Chuỗi là UTF-16, vì vậy việc ghi vào StringWriter sẽ luôn sử dụng UTF-16. Nếu đó không phải là những gì bạn muốn, sau đó sử dụng một số lớp học khác có nguồn gốc TextWriter, với mã hóa bạn thích.

+1

Lắc đầu. Vì vậy, điểm là gì sau đó có một tài sản mã hóa trên XmlWriterSettings. Có một chuỗi là UTF-16, nhưng nếu chúng ta đang tuần tự hóa thành một chuỗi, bởi vì chúng ta sắp viết vào một tệp hoặc một cái gì đó, và chúng ta muốn thuộc tính mã hóa của khai báo xml khớp với mã hóa thực của tệp chúng ta tạo và điều này có vẻ không phải là UTF-16. – bbsimonbb

+0

@user không tuần tự hóa thành chuỗi sẽ chuyển trực tiếp đến Luồng. –

+0

OK. Điều đó có ý nghĩa hơn. – bbsimonbb

14

Theo như tôi biết, lớp StringWriter sẽ luôn sử dụng mã hóa UTF 16 khi tuần tự hóa thành chuỗi. Bạn có thể viết lớp override của riêng bạn mà chấp nhận một mã hóa khác nhau:

public class StringWriterWithEncoding : StringWriter 
{ 
    private readonly Encoding _encoding; 

    public StringWriterWithEncoding() 
    { 
    } 

    public StringWriterWithEncoding(IFormatProvider formatProvider) 
     : base(formatProvider) 
    { 
    } 

    public StringWriterWithEncoding(StringBuilder sb) 
     : base(sb) 
    { 
    } 

    public StringWriterWithEncoding(StringBuilder sb, IFormatProvider formatProvider) 
     : base(sb, formatProvider) 
    { 
    } 


    public StringWriterWithEncoding(Encoding encoding) 
    { 
     _encoding = encoding; 
    } 

    public StringWriterWithEncoding(IFormatProvider formatProvider, Encoding encoding) 
     : base(formatProvider) 
    { 
     _encoding = encoding; 
    } 

    public StringWriterWithEncoding(StringBuilder sb, Encoding encoding) 
     : base(sb) 
    { 
     _encoding = encoding; 
    } 

    public StringWriterWithEncoding(StringBuilder sb, IFormatProvider formatProvider, Encoding encoding) 
     : base(sb, formatProvider) 
    { 
     _encoding = encoding; 
    } 

    public override Encoding Encoding 
    { 
     get { return (null == _encoding) ? base.Encoding : _encoding; } 
    } 
} 

Vì vậy, bạn có thể sử dụng thay vì:

using(var stringWriter = new StringWriterWithEncoding(Encoding.UTF8)) 
{ 
    ... 
} 
+0

Big +1, làm việc tốt , cảm ơn bạn. –

1

Bạn nên lấy một lớp mới từ StringWriter trong đó có một đặc tính mã hóa ghi đè.

1

Khi câu trả lời được chấp nhận cho biết, StringWriter là UTF-16 (Unicode) theo mặc định và thiết kế. Nếu bạn muốn làm điều đó bằng cách nhận được một chuỗi UTF-8 cuối cùng, có 2 cách tôi có thể cung cấp cho bạn để hoàn thành nó:

Giải pháp # 1 (không thực sự rất hiệu quả, xấu, nhưng nhận được công việc thực hiện): Đổ nó vào một tập tin văn bản và đọc nó trở lại, xóa tập tin (có lẽ chỉ thích hợp cho các tập tin nhỏ, nếu bạn thậm chí muốn làm điều này cả - chỉ muốn hiển thị nó có thể được thực hiện!)

public static string SerializeObject<T>(this T value) 
{ 
    var serializer = new XmlSerializer(typeof(T));   
    var settings = new XmlWriterSettings 
        { 
        Encoding = new UTF8Encoding(true), 
        Indent = false, 
        OmitXmlDeclaration = false, 
        NewLineHandling = NewLineHandling.None 
        }; 


    using(var xmlWriter = XmlWriter.Create("MyFile.xml", settings)) 
    { 
     serializer.Serialize(xmlWriter, value); 
    } 

    XmlDocument xml = new XmlDocument(); 
    xml.Load("MyFile.xml"); 
    byte[] bytes = Encoding.UTF8.GetBytes(xml.OuterXml);   
    File.Delete("MyFile.xml"); 

    return Encoding.UTF8.GetString(bytes); 

} 

giải pháp # 2 (tốt hơn, dễ dàng hơn, giải pháp thanh lịch hơn!): làm điều đó như bạn có nó, sử dụng StringWriter, nhưng sử dụng nó Encoding tài sản để thiết lập nó sang UTF-8:

public static string SerializeObject<T>(this T value) 
{ 
    var serializer = new XmlSerializer(typeof(T));   
    var settings = new XmlWriterSettings 
        { 
        Encoding = new UTF8Encoding(true), 
        Indent = false, 
        OmitXmlDeclaration = false, 
        NewLineHandling = NewLineHandling.None 
        }; 

    using(var stringWriter = new StringWriter(Encoding.UTF8)) 
    { 
     using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) 
     { 
      serializer.Serialize(xmlWriter, value); 
     } 

     return stringWriter.ToString(); 
    } 
} 
+0

Tôi có thiếu cái gì ở đây? StringWriter' không xuất hiện để có một tài sản Encoding như là một đối số constructor. – crush

Các vấn đề liên quan