stringwriter encoding utf 8 c#
¿Por qué el XmlWriter siempre está generando la codificación utf-16? (4)
Como dice la respuesta aceptada, StringWriter
es UTF-16 (Unicode) por defecto y diseño. Si quieres hacerlo obteniendo una cadena UTF-8 al final, hay dos formas en que puedo darte para que lo hagas:
Solución # 1 (no muy eficiente, mala práctica, pero hace el trabajo): vacíelo en un archivo de texto y vuelva a leerlo, elimínelo (probablemente solo sea adecuado para archivos pequeños, si es que desea hacerlo) - 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 (¡solución mejor, más fácil, más elegante!): Hágalo como lo tiene, usando StringWriter
, pero use su propiedad de Encoding
para configurarlo en 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;
}
}
}
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 siempre que lo llamo tiene una codificación de utf-16
especificada, es decir, <?xml version="1.0" encoding="utf-16"?>
. ¿Qué estoy haciendo mal?
Debería derivar una nueva clase de StringWriter que tiene una propiedad de codificación anulada.
Las cadenas son UTF-16, por lo que escribir en un StringWriter siempre usará UTF-16. Si eso no es lo que quiere, entonces use alguna otra clase derivada de TextWriter
, con la codificación que desee.
Por lo que sé, la clase StringWriter siempre usará la codificación UTF 16 al serializar una cadena. Puede escribir su propia clase de anulación que acepte 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 puedes usar esto en su lugar:
using(var stringWriter = new StringWriterWithEncoding( Encoding.UTF8))
{
...
}