Tengo este método de extensió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 stringWriter = new StringWriter()) 
        {
            using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) 
            {
                serializer.Serialize(xmlWriter, value);
            }

            return stringWriter.ToString();
        }
    }

pero cada vez que yo llamo a esto tiene una codificación de utf-16 especificado, es decir,<?xml version="1.0" encoding="utf-16"?>. ¿Qué estoy haciendo mal?

InformationsquelleAutor Glenn Slaven | 2012-02-27

6 Comentarios

  1. 16

    Son las cadenas de caracteres UTF-16, por lo que escribir para un StringWriter siempre use UTF-16. Si eso no es lo que desea, a continuación, utilizar algunos otros TextWriter clase derivada, con la codificación que te gusta.

    • Sacude la cabeza. ¿Cuál es el punto luego de tener una propiedad de codificación en el XmlWriterSettings. Sí una cadena UTF-16, pero si queremos serializar a una cadena, porque estamos a punto de escribir a un archivo o algo, y queremos que el atributo de codificación de la declaración xml a la altura real de la codificación del archivo que queremos crear, y es poco probable que sea UTF-16.
    • no serializar a una cadena de ir directamente a un Arroyo.
    • OK. Eso tiene más sentido.
    • Sí, usted está utilizando StringWriter, así que por defecto es Unicode (UTF-16) . Si hago using(var xmlWriter = XmlWriter.Create("MyFile.xml", settings) y hacer un manual xmlWriter.WriteStartElement("SomeRootElement"); xmlWriter.WriteEndElement();, a continuación, cargar de nuevo: XmlDocument xml = new XmlDocument(); xml.Load("MyFile.xml"); byte[] bytes = Encoding.Default.GetBytes(xml.OuterXml); string xmlDoc = Encoding.Default.GetString(bytes);, es UTF-8 – sólo para tu INFORMACIÓN que se puede volcar a un archivo y leer de nuevo, a continuación, elimine el archivo. Como alternativa, utilice StringWriter, sólo tiene que especificar Encoding.UTF8.
  2. 15

    Hasta donde yo sé, StringWriter clase siempre use UTF 16 de codificación cuando se serializan en cadena. Usted puede escribir su propio override de la clase que acepta una codificación diferente:

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

    Así que usted puede utilizar esto en su lugar:

    using(var stringWriter = new StringWriterWithEncoding( Encoding.UTF8))
    {
       ...
    }
    • Grande +1, funcionan bien, gracias.
  3. 1

    como @juan-saunders mencionó en su respuesta:

    StringWriter siempre use UTF-16

    Lo que he usado MemoryStream para este fin.

    En mi caso yo uso windows-1251 de codificación.

    var xmlSstring = "";
    using (var ms = new MemoryStream())
    {
        var encoding = Encoding.GetEncoding(1251);
        var settings = new XmlWriterSettings
        {
            Indent = true,
            Encoding = encoding
        };
    
        using (var xmlTextWriter = XmlWriter.Create(ms, settings))
        {
            doc.Save(xmlTextWriter);
            xmlString = encoding.GetString(ms.ToArray());
        }
    }
  4. 0

    Como el aceptado la respuesta, dice, StringWriter es UTF-16 (Unicode) por defecto y el diseño. Si quieres hacer que una cadena UTF-8 en el final, hay 2 maneras en las que puedo dar a usted para hacerlo:

    Solución #1 (no muy eficiente, una mala práctica, pero hace el trabajo): Volcado a un archivo de texto y la lectura, elimine el archivo (probablemente sólo apto para archivos pequeños, incluso si lo quieres hacer todo esto – sólo quería mostrar que se podía hacer!)

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

    Solución #2 (mejor, más fácil, más elegante solución!): ¿como la tienes, utilizando StringWriter, pero el uso de su Encoding propiedad para establecer a 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 UTF8StringWriter())
        {
            using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) 
            {
                serializer.Serialize(xmlWriter, value);
            }
    
            return stringWriter.ToString();
        }
    }
    
    public class UTF8StringWriter : StringWriter
    {
        public override Encoding Encoding
        {
            get
            {
                return Encoding.UTF8;
            }
        }
    }
  5. 0

    Si usted no desea utilizar una clase que deriva de StringWriter, a continuación, en su caso, usted podría simplemente establecer el OmitXmlDeclaration a false y declarar su propia cuenta, tal como hago a continuación:

     public static string Serialize<T>(this T value, string xmlDeclaration = "<?xml version=\"1.0\"?>") where T : class, new()
            {
                if (value == null) return string.Empty;
    
                using (var stringWriter = new StringWriter())
                {
                    var settings = new XmlWriterSettings
                    {
                        Indent = true,
                        OmitXmlDeclaration = xmlDeclaration != null,
                    };
    
                    using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
                    {
                        var xmlSerializer = new XmlSerializer(typeof(T));
    
                        xmlSerializer.Serialize(xmlWriter, value);
    
                        var sb = new StringBuilder($"{Environment.NewLine}{stringWriter}");
    
                        sb.Insert(0, xmlDeclaration);
    
                        return sb.ToString();
                    }
                }

Dejar respuesta

Please enter your comment!
Please enter your name here