BinaryFormatter 序列化 API 生成编译器错误
作为 BinaryFormatter 长期弃用计划的一部分,我们将继续从我们的库中剔除 BinaryFormatter
功能,并让开发人员不再依赖这种类型。 从 .NET 7 开始,对以下 API 的调用会在所有 C# 和 Visual Basic 项目类型中生成编译时错误:
- System.Exception.SerializeObjectState 事件
- BinaryFormatter.Serialize 方法
- BinaryFormatter.Deserialize 方法
- Formatter.Serialize(Stream, Object) 方法
- Formatter.Deserialize(Stream) 方法
- IFormatter.Serialize(Stream, Object) 方法
- IFormatter.Deserialize(Stream) 方法
旧行为
从 .NET 5 开始,使用受影响的 Serialize
和 Deserialize
方法会生成 ID 为 SYSLIB0011
的编译器警告。 有关详细信息,请参阅 BinaryFormatter 序列化方法已过时,并且已在 ASP.NET 应用 (.NET 5) 中禁用。
使用 Exception.SerializeObjectState 事件不会生成错误。
新行为
从 .NET 7 开始,在代码中使用任何受影响的 API 都会生成 ID 同为 SYSLIB0011
的编译器错误。 如果项目满足以下所有条件,将受到影响:
- 是 C# 或 Visual Basic 项目。
- 面向
net7.0
或更高版本。 - 直接调用受影响的 API 之一。
- 尚未取消
SYSLIB0011
警告代码。
引入的版本
.NET 7
中断性变更的类型
此项更改可能会影响源兼容性。
更改原因
作为 BinaryFormatter 长期弃用计划的一部分,我们将继续从我们的库中剔除 BinaryFormatter
功能,并让开发人员不再依赖这种类型。
建议的操作
由于 BinaryFormatter
的安全性和可靠性缺陷,最好的做法是从其迁移。 BinaryFormatter
可能会在未来版本中从 .NET 中删除。 .NET 库团队已经表明最近的类型(例如 System.Half 和 System.DateOnly)将与 BinaryFormatter
不兼容。
如果必须取消错误,可以按照原始过时文章中的指南进行操作。 还可以通过对将错误转换回警告(以匹配 .NET 5/6 行为)的项目属性进行设置,在项目范围内禁用错误。
警告
设置此属性可能会更改主机行为。 请参阅 <EnableUnsafeBinaryFormatterSerialization> 属性。
<PropertyGroup>
...
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
注意
如果项目编译时启用了“将警告视为错误”,编译仍将失败。 (这与 .NET 5 和 .NET 6 SDK 中提供的行为相匹配。)如果是这种情况,则仍然需要在源或项目文件的 <NoWarn>
元素中取消 SYSLIB0011
警告。
<EnableUnsafeBinaryFormatterSerialization> 属性
<EnableUnsafeBinaryFormatterSerialization
属性是在 .NET 5 中引入的。 在 .NET 7 中,此开关的行为已更改为同时控制编译和主机运行时行为。 此开关的含义因项目类型而异,如下表所述。
项目类型 | 属性设置为 true |
属性设置为 false |
省略属性 |
---|---|---|---|
库/共享组件1 | 受影响的 API 已过时,报告为警告。 除非为应用程序启用了“将警告视为错误”或已取消 SYSLIB0011 警告代码,否则编译将成功。 |
受影响的 API 已过时并报告为错误,并且从代码调用这些 API 将在编译时失败,除非取消错误。 | (与 false 相同。) |
Blazor 和 MAUI 应用2 | 对 BinaryFormatter 的调用将在运行时失败。 |
对 BinaryFormatter 的调用将在运行时失败。 |
对 BinaryFormatter 的调用将在运行时失败。 |
ASP.NET 应用 | 受影响的 API 已过时,报告为警告。 除非为应用程序启用了“将警告视为错误”或已取消 SYSLIB0011 警告代码,否则编译将成功。 无论调用源自代码还是来自使用的依赖项,运行时都将允许调用 BinaryFormatter 。 |
受影响的 API 已过时并报告为错误,并且从代码调用这些 API 将在编译时失败,除非取消错误。 无论调用源自代码还是来自使用的依赖项,运行时都将禁止调用 BinaryFormatter 。 |
(与 false 相同。) |
桌面应用和所有其他应用类型 | 受影响的 API 已过时,报告为警告。 除非为应用程序启用了“将警告视为错误”或已取消 SYSLIB0011 警告代码,否则编译将成功。 无论调用源自代码还是来自使用的依赖项,运行时都将允许调用 BinaryFormatter 。 |
受影响的 API 已过时并报告为错误,并且从代码调用这些 API 将在编译时失败,除非取消错误。 无论调用源自代码还是来自使用的依赖项,运行时都将禁止调用 BinaryFormatter 。 |
受影响的 API 已过时并报告为错误,从代码调用这些 API 将在编译时失败,除非取消错误。 无论调用源自代码还是来自使用的依赖项,运行时都将允许调用 BinaryFormatter 。 |
1运行时策略由应用主机控制。 即使在库的项目文件中将 <EnableUnsafeBinaryFormatterSerialization>
设置为 true
,对 BinaryFormatter
的调用仍可能在运行时失败。 库无法替代应用主机的运行时策略。
2Blazor 和 MAUI 运行时禁止调用 BinaryFormatter
。 无论为 <EnableUnsafeBinaryFormatterSerialization>
设置何种值,调用都会在运行时失败。 请勿从 Blazor 或 MAUI 应用程序或打算由 Blazor 或 MAUI 应用使用的库调用这些 API。
受影响的 API
- System.Exception.SerializeObjectState
- System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
- System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize
- System.Runtime.Serialization.Formatter.Serialize(Stream, Object)
- System.Runtime.Serialization.Formatter.Deserialize(Stream)
- System.Runtime.Serialization.IFormatter.Serialize(Stream, Object)
- System.Runtime.Serialization.IFormatter.Deserialize(Stream)