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
方法會產生識別碼為 SYSLIB0011
的編譯器「警告」。 如需詳細資訊,請參閱 BinaryFormatter 序列化方法在 ASP.NET 應用程式 (.NET 5) 中已淘汰並禁止。
使用 Exception.SerializeObjectState 事件不會產生錯誤。
新的行為
從 .NET 7 開始,在程式碼中使用任何受影響 的 API 會產生具有相同識別碼 SYSLIB0011
的編譯程式「錯誤」。 如果您的專案符合下列所有準則,則將會受到影響:
- 其為 C# 或 Visual Basic 專案。
- 其鎖定
net7.0
或更高版本。 - 其直接呼叫其中一個受影響 API。
- 其尚未隱藏
SYSLIB0011
警告碼。
導入的版本
.NET 7
中斷性變更的類型
此變更可能會影響來源相容性。
變更原因
在 BinaryFormatter 長期淘汰方案中,我們會繼續從程式庫擷取 BinaryFormatter
功能,並讓開發人員放棄類型。
建議的動作
最佳動作時程是因安全性和可靠性瑕疵而離開 BinaryFormatter
。 未來的版本可能會從 .NET 中移除 BinaryFormatter
。 .NET 程式庫小組所採取的態度是最新類型 (例如 System.Half 和 System.DateOnly) 將不會與 BinaryFormatter
相容。
如果您必須隱藏錯誤,則作法是遵循原始淘汰文章中的指導方針。 您也可以設定將錯誤轉換回警告 (以符合 .NET 5/6 行為) 的專案屬性,以停用整個專案的錯誤。
警告
設定此屬性可能會變更主機行為。 請參閱 <EnableUnsafeBinaryFormatterSerialization> 屬性。
<PropertyGroup>
...
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
注意
如果您的專案在啟用「警告為錯誤」的情況下進行編譯,則編譯仍然會失敗。 (這符合 .NET 5 和 .NET 6 SDK 中附帶的行為。)如果是這種情況,則您仍然需要隱藏來源或專案檔 <NoWarn>
元素中的 SYSLIB0011
警告。
<EnableUnsafeBinaryFormatterSerialization> 屬性
已在 .NET 5 中引進 <EnableUnsafeBinaryFormatterSerialization
屬性。 在 .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)