Once you need to generate a XML document in your ASP.NET application (for example, to offer it for download), you will sooner or later decide to use the
XMLWriter class of .NET Fx.
So you’ll write a piece of code like:
string fileName = buildDownloadFilename();
XDocument xmlDocument = generateXML();
if (xmlDocument != null)
{
StringBuilder sb = new StringBuilder();
XmlWriter xmlWriter = XmlWriter.Create(sb);
xmlDocument.Save(xmlWriter);
xmlWriter.Close();
string strContent = sb.ToString();
Response.ContentType = "text/xml";
Response.AppendHeader("content-disposition", String.Format("attachment;filename={0}", fileName));
Response.AppendHeader("Content-Length", strContent.Length.ToString());
Response.Write(strContent);
And you’ll be definitely surprised seeing the output XML declaration with encoding “UTF-16”.
Well, extending the code snippet with explicit
XMLWriterSettings, you’ll land on:
string fileName = buildDownloadFilename();
XDocument xmlDocument = generateXML();
if (xmlDocument != null)
{
StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
XmlWriter xmlWriter = XmlWriter.Create(sb, settings);
xmlDocument.Save(xmlWriter);
xmlWriter.Close();
string strContent = sb.ToString();
Response.ContentType = "text/xml";
Response.AppendHeader("content-disposition", String.Format("attachment;filename={0}", fileName));
Response.AppendHeader("Content-Length", strContent.Length.ToString());
Response.Write(strContent);
And you’ll be still surprised seeing the output XML declaration unchanged with encoding “UTF-16”.
The reason is,
the settings of XMLWriter target (in this sample – StringBuilder) override the XMLWriterSettings parameters already in XMLWriter constructor.
The way out is, use an alternate target for XMLWriter, supporting the encoding you need. For example:
string fileName = buildDownloadFilename();
XDocument xmlDocument = generateXML();
if (xmlDocument != null)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
MemoryStream ms = new MemoryStream();
XmlWriter xmlWriter = XmlWriter.Create(ms, settings);
xmlDocument.Save(xmlWriter);
xmlWriter.Close();
string strContent = Encoding.UTF8.GetString(ms.GetBuffer());
Response.ContentType = "text/xml";
Response.AppendHeader("content-disposition", String.Format("attachment;filename={0}", fileName));
Response.AppendHeader("Content-Length", strContent.Length.ToString());
Response.Write(strContent);
Also check the solution here:
http://blogs.msdn.com/b/kaevans/archive/2008/08/11/xmlwritersettings-encoding-being-ignored.aspx
Enjoy!