Как вернуть xml как UTF-8 вместо UTF-16
Я использую процедуру, которая сериализует <T>
. Он работает, но при загрузке в браузер я вижу пустую страницу. Я могу просмотреть источник страницы или открыть загрузку в текстовом редакторе, и я вижу xml, но это в UTF-16, который я думаю, почему страницы браузера показывают пустые?
как изменить мою процедуру сериализатора для возврата UTF-8 вместо UTF-16?
возвращенный источник XML:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>January</string>
<string>February</string>
<string>March</string>
<string>April</string>
<string>May</string>
<string>June</string>
<string>July</string>
<string>August</string>
<string>September</string>
<string>October</string>
<string>November</string>
<string>December</string>
<string />
</ArrayOfString>
пример вызова сериализатор:
DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo();
var months = dateTimeFormatInfo.MonthNames.ToList();
string SelectionId = "1234567890";
return new XmlResult<List<string>>(SelectionId)
{
Data = months
};
Сериализатор:
public class XmlResult<T> : ActionResult
{
private string filename = DateTime.Now.ToString("ddmmyyyyhhss");
public T Data { private get; set; }
public XmlResult(string selectionId = "")
{
if (selectionId != "")
{
filename = selectionId;
}
}
public override void ExecuteResult(ControllerContext context)
{
HttpContextBase httpContextBase = context.HttpContext;
httpContextBase.Response.Buffer = true;
httpContextBase.Response.Clear();
httpContextBase.Response.AddHeader("content-disposition", "attachment; filename=" + filename + ".xml");
httpContextBase.Response.ContentType = "text/xml";
using (StringWriter writer = new StringWriter())
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(writer, Data);
httpContextBase.Response.Write(writer);
}
}
}
3 ответов
кодировка ответа
Я не совсем знаком с этой частью структуры. Но в соответствии с MSDN вы можете установить кодировка содержимого HttpResponse такой:
httpContextBase.Response.ContentEncoding = Encoding.UTF8;
кодировка, как видно из XmlSerializer
после прочтения вашего вопроса снова я вижу, что это сложная часть. Проблема заключается в использовании StringWriter
. Поскольку строки .NET всегда хранятся как UTF-16 (необходима цитата^^), StringWriter
возвращает это в качестве кодировки. Таким образом XmlSerializer
записывает XML-объявление как
<?xml version="1.0" encoding="utf-16"?>
чтобы обойти это, вы можете написать в MemoryStream следующим образом:
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(writer, Data);
// I am not 100% sure if this can be optimized
httpContextBase.Response.BinaryWrite(stream.ToArray());
}
другие подходы
другое редактирование: я только что заметил это так ответ связанный jtm001. Конденсированное решение существует, чтобы обеспечить XmlSerializer
с пользовательским XmlWriter
, который настроен на использование utf8 в качестве кодировки.
Асари предлагает происходит от StringWriter
и рекламируйте кодировку как UTF8.
насколько я понимаю, оба решения также должны работать. Я думаю, что вынос здесь заключается в том, что вам понадобится тот или иной тип шаблонного кода...
Вы можете использовать StringWriter, который заставит UTF8. Вот один из способов сделать это:
public class Utf8StringWriter : StringWriter
{
// Use UTF8 encoding but write no BOM to the wire
public override Encoding Encoding
{
get { return new UTF8Encoding(false); } // in real code I'll cache this encoding.
}
}
а затем используйте utf8stringwriter writer в своем коде.
using (StringWriter writer = new Utf8StringWriter())
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(writer, Data);
httpContextBase.Response.Write(writer);
}
ответ вдохновлен сериализовать объект в UTF-8 XML в .Чистая
для сериализации в виде строки UTF8:
private string Serialize(MyData data)
{
XmlSerializer ser = new XmlSerializer(typeof(MyData));
// Using a MemoryStream to store the serialized string as a byte array,
// which is "encoding-agnostic"
using (MemoryStream ms = new MemoryStream())
// Few options here, but remember to use a signature that allows you to
// specify the encoding
using (XmlTextWriter tw = new XmlTextWriter(ms, Encoding.UTF8))
{
tw.Formatting = Formatting.Indented;
ser.Serialize(tw, data);
// Now we get the serialized data as a string in the desired encoding
return Encoding.UTF8.GetString(ms.ToArray());
}
}
чтобы вернуть его в виде XML в веб-ответе, не забудьте установить кодировку ответа:
string xml = Serialize(data);
Response.ContentType = "application/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.Output.Write(xml);