c# - XmlSerializer.Serialize BOM 缺失

标签 c# xmlserializer

我使用此代码来存储我的类:

FileStream stream = new FileStream(myPath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(myClass));
serializer.Serialize(stream, myClass);
stream.Close();

这会写入一个我可以用 XmlSerializer.Deserialize 读取的文件。但是,生成的文件不是正确的文本文件。 XmlSerializer.Serialize不存储 BOM,但仍插入多字节字符。因此,它被隐式声明为 ANSI 文件(因为我们期望 XML 文件是文本文件,而没有 BOM 的文本文件被 Windows 视为 ANSI),在某些编辑器中将 ö 显示为 à。

这是一个已知的错误吗?或者我缺少一些设置?

这是生成的文件的开头:

<?xml version="1.0"?>
<SvnProjects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

文件中的第一个字节是十六进制3C,即< .

最佳答案

有或没有 BOM 并不是“正确文本文件”的定义。事实上,我想说现在最典型的格式是 UTF-8 without BOM;我不认为我曾经见过有人在实际系统中实际使用 UTF-8 BOM!但是:如果您想要 BOM,那没问题:只需传入正确的 Encoding 即可;如果你想要带有 BOM 的 UTF-8:

using (var writer = XmlWriter.Create(myPath, s_settings))
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    serializer.Serialize(writer, obj);
}

与:

static readonly XmlWriterSettings s_settings =
    new XmlWriterSettings { Encoding = new UTF8Encoding(true) };

结果是一个以 EF-BB-BF(UTF-8 BOM)开头的文件。

如果您想要不同编码,只需将new UTF8Encoding替换为您想要的任何内容,记住启用BOM。

(注意:静态 Encoding.UTF8 实例启用了 BOM,但在我看来,如果您特别打算使用 BOM,最好在这里非常明确,就像您应该非常明确一样关于您打算使用的编码)


编辑:这里的主要区别是 Serialize(Stream, object) 最终使用:

XmlTextWriter xmlWriter = new XmlTextWriter(stream, encoding: null) {
    Formatting = Formatting.Indented,
    Indentation = 2
};

最终使用:

public StreamWriter(Stream stream) : this(stream,
    encoding: UTF8NoBOM, // <==== THIS IS THE PROBLEM
    bufferSize: 1024, leaveOpen: false)
{
}

所以:如果您使用该 API,则默认使用无 BOM 的 UTF-8。

关于c# - XmlSerializer.Serialize BOM 缺失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56884551/

相关文章:

c# - 使用 gmail 发送电子邮件。错误 : The server response was: 5. 5.1 需要身份验证

C#,为什么 XmlSerializer 序列化基础对象而不是接口(interface)?

c# - XMLSerializer - 无参数构造

c# - 序列化容器类时如何忽略特定的 List<T> 项

c# - 资源字典中带有标题的多个项目组合框?

c# - 从 Web Browser 组件获取整页截图

c# - 在 C# 中将 RTF 文件转换为 PDF

c# - 是否可以将复杂类型属性绑定(bind)到数据网格?

c# - XmlSerializer 在 .net framework 和 .net core 上与属性的私有(private) getter 行为不同

C# XmlSerializer 绑定(bind)失败