XmlSerializer编码配置报错,生成XML时UTF8变UTF16如何解决?
XML序列化编码问题的修复方案
问题原因拆解
1. 传入encoding.EncodingName报错的原因
你调用的XmlSerializer.Serialize重载中,第四个string参数并非编码名称,它的作用是指定「当序列化对象的根元素无显式命名空间时使用的默认命名空间」。你已经传入了xmlns(XmlSerializerNamespaces对象),再传编码名称完全不符合参数设计,必然报错。
2. 依赖XmlWriterSettings.Encoding却生成UTF16的原因
你使用StringBuilder作为输出目标,而StringBuilder存储的是.NET标准的UTF-16字符(所有.NET字符串默认都是UTF-16编码)。此时XmlWriterSettings.Encoding会被忽略——因为XmlWriter直接写入字符到内存字符串,无需编码为字节,所以XML声明自动显示encoding="utf-16"。
修复方案
根据实际需求选择对应方案:
方案1:生成UTF8编码的XML字符串(带正确声明)
放弃StringBuilder,改用MemoryStream存储字节流,再转换为UTF8字符串:
var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; using (var ms = new MemoryStream()) using (var xmlWriter = XmlWriter.Create(ms, settings)) { var serializer = new XmlSerializer(model.GetType()); serializer.Serialize(xmlWriter, model, xmlns); ms.Position = 0; using (var reader = new StreamReader(ms, Encoding.UTF8)) { string xmlString = reader.ReadToEnd(); // xmlString即为带utf-8声明的正确XML内容 } }
方案2:直接写入文件/网络流
如果不需要中间字符串,直接将目标流传给XmlWriter.Create,此时XmlWriterSettings.Encoding会正常生效,XML声明会正确显示utf-8:
var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; using (var fs = new FileStream("output.xml", FileMode.Create)) using (var xmlWriter = XmlWriter.Create(fs, settings)) { var serializer = new XmlSerializer(model.GetType()); serializer.Serialize(xmlWriter, model, xmlns); }
备选方案(仅修改字符串显示,不推荐)
若必须使用StringBuilder,可手动替换XML声明中的编码标识,但注意这只是表面修改,实际字符串仍是UTF-16编码:
var strbuilder = new StringBuilder(); var settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = false }; using (var xmlWriter = XmlWriter.Create(strbuilder, settings)) { var serializer = new XmlSerializer(model.GetType()); serializer.Serialize(xmlWriter, model, xmlns); } // 替换编码声明 string xmlString = strbuilder.ToString().Replace("encoding=\"utf-16\"", "encoding=\"utf-8\"");
内容的提问来源于stack exchange,提问作者lonelydev101
相关产品推荐
相关产品推荐

