作为 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 中附带的行为匹配。如果是这种情况,仍需要在源或项目文件的SYSLIB0011元素中取消<NoWarn>警告。
<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运行时策略由应用主机控制。 即使在库的项目文件中已将BinaryFormatter设置为<EnableUnsafeBinaryFormatterSerialization>,运行时对true的调用仍可能失败。 库不能替代应用主机的运行时策略。
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)