-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Breaking change]: Legacy serialization infrastructure APIs marked obsolete #34893
Comments
@GrabYourPitchforks Should we check the 'Behavioral change' checkbox too since running an existing library in an updated runtime will yield different behavior? |
@jeffhandley I had opened a different issue #34891 for that. One issue tracks the behavioral change; one issue tracks the new obsoletions. I did it this way because each issue requires its own resolution strategy, and most app authors only need one or the other (but not both). If this is confusing we could certainly combine the issues! |
Ah, gotcha! Thanks for the clarification. |
These changes will go into effect in .NET 8 Preview 4. At that time, folks are likely to observe Since we will be routing folks to this issue, but we won't be actively monitoring this issue for comments, we are going to lock the conversation. If you experience an issue that is not already covered in the description of these changes, please file a new issue in the |
In this case, I think CA2237: |
Description
Beginning with .NET 8 Preview 4, most of the legacy serialization infrastructure (the infrastructure which supports
SerializableAttribute
andISerializable
, along with infrastructure which supportsBinaryFormatter
) is obsolete.Additionally, the entirety of the type
BinaryFormatter
is now obsolete as error.(See related breaking change notification #34891.)
Version
.NET 8 Preview 4
Previous behavior
In .NET 7, the
Serialize
andDeserialize
methods onBinaryFormatter
,IFormatter
, andFormatter
were marked obsolete. The types themselves, however, were not marked obsolete. The full list of APIs marked obsolete in .NET 7 is provided at the .NET 7 breaking change notification document.New behavior
Beginning with .NET 8 Preview 4, the entirety of the
BinaryFormatter
,IFormatter
, andFormatter
types are marked obsolete as error. Code which references these types - even if it does not call theSerialize
orDeserialize
method - will observe compilation failures on .NET 8.Additionally, beginning with .NET 8 Preview 4, many types and APIs which support the legacy serialization infrastructure are marked obsolete as warning. Other APIs are marked
[EditorBrowsable(EditorBrowsableState.Never)]
, which causes these APIs to be hidden from the Visual Studio IDE.See below for resolution strategies, including getting existing code which relied on
BinaryFormatter
to compile successfully.Type of breaking change
Reason for change
This is the next stage of the BinaryFormatter obsoletion plan, preparing for BinaryFormatter's eventual removal from .NET. See earlier breaking change notifications for additional context:
Recommended action
If you're using BinaryFormatter
The best course of action is to migrate away from it due to its security and reliability flaws. See https://aka.ms/binaryformatter for more information. If necessary, you can suppress the compilation error by following the steps in the Recommended action section of the .NET 7 breaking change notification.
If you're using FormatterServices.GetUninitializedObject
Use
RuntimeHelpers.GetUninitializedObject
instead.If you're cross-compiling for .NET Framework and modern .NET, you can use an
#if
statement to selectively call the appropriate API, as shown below.If you're creating a custom System.Exception-derived type
Consider whether you truly need your custom exception type to be serializable. Chances are you do not need it to be serializable, as exception serialization is primarily intended to support remoting, and support for remoting was dropped in .NET Core 1.0.
If you have defined your custom exception type like this:
Consider simply removing the
[Serializable]
attribute, the serialization constructor, and theGetObjectData
method override, as shown below.There may be some cases where you cannot remove these APIs from your custom exception types. This might occur if you produce a library constrained by API compatibility requirements. In this case, the recommendation is to obsolete your own serialization constructor and
GetObjectData
methods using theSYSLIB0051
diagnostic code, as shown below. Since ideally nobody outside the serialization infrastructure itself should be calling these APIs, this should only impact other types which subclass your custom exception type. It should not virally impact anybody catching, constructing, or otherwise using your custom exception type.If you're cross-targeting for .NET Framework and .NET 8+, you can use an
#if
statement to apply the obsoletion conditionally. This is the same strategy we use within the .NET libraries code base when we're cross-targeting runtimes.If you're writing your own standalone serializable type
If you're declaring a custom type which is marked
[Serializable]
or which implements theISerializable
interface, you should not see any compilation warnings as a result of this change unless you've implemented a less common code pattern. For example, the code below should not see any warnings.However, .NET recommends against annotating your types in this manner, as modern serialization libraries do not require such annotations. Instead, consider leaving off the
[Serializable]
attribute and theISerializable
interface, instead relying on your serialization library to access your object through its public properties rather than its private fields.If you're subclassing an existing .NET type which is marked
[Serializable]
and you're observingSYSLIB0051
warning codes, see the earlier section on creating custom exception types. The overall pattern described there remains generally applicable.If you're writing a serialization library
Microsoft strongly recommends against serialization libraries supporting the legacy serialization infrastructure (
[Serializable]
andISerializable
). Modern serialization libraries should have policy based on a type's public APIs rather than its private implementation details. Basing a serializer on these implementation details and strongly tying it toISerializable
and other mechanisms which encourage embedding type names within the serialized payload can lead to many of the same problems called out in https://aka.ms/binaryformatter.If your serialization library must remain compatible with the legacy serialization infrastructure, you can easily suppress the legacy serialization API obsoletions (the
SYSLIB0050
category) project-wide by putting the following block in your.csproj
,.vbproj
, or directory-level.props
file.Feature area
Serialization
Affected APIs
The following types are marked obsolete as warning with obsoletion code
SYSLIB0050
.System.Runtime.Serialization.FormatterConverter
System.Runtime.Serialization.FormatterServices
System.Runtime.Serialization.IFormatterConverter
System.Runtime.Serialization.IObjectReference
System.Runtime.Serialization.ISafeSerializationData
System.Runtime.Serialization.ISerializationSurrogate
System.Runtime.Serialization.ISurrogateSelector
System.Runtime.Serialization.ObjectIDGenerator
System.Runtime.Serialization.ObjectManager
System.Runtime.Serialization.SafeSerializationEventArgs
System.Runtime.Serialization.SerializationObjectManager
System.Runtime.Serialization.StreamingContextStates
System.Runtime.Serialization.SurrogateSelector
System.Runtime.Serialization.Formatters.FormatterAssemblyStyle
System.Runtime.Serialization.Formatters.FormatterTypeStyle
System.Runtime.Serialization.Formatters.IFieldInfo
System.Runtime.Serialization.Formatters.TypeFilterLevel
The following APIs are marked obsolete as warning with obsoletion code
SYSLIB0050
.System.Type.IsSerializable
property (and all overridden implementations)System.Reflection.FieldAttributes.NotSerialized
enum value (but not theFieldAttributes
enum type itself)System.Reflection.FieldInfo.IsNotSerialized
propertySystem.Reflection.TypeAttributes.Serializable
enum value (but not theTypeAttributes
enum type itself)System.Runtime.Serialization.ISerializable.GetObjectData
method (but not theISerializable
type itself)System.Runtime.Serialization.SerializationInfo
(but not theSerializationInfo
type itself)System.Runtime.Serialization.StreamingContext
(but not theStreamingContext
type itself)The following APIs are marked obsolete as warning with obsoletion code
SYSLIB0051
..ctor(SerializationInfo, StreamingContext)
. An example of such a constructor is the serialization constructor on theSystem.Exception
type.IObjectReference.GetRealObject
method. An example of such a method isSystem.Reflection.ParameterInfo.GetRealObject
.ISerializable.GetObjectData
method. An example of such a method isSystem.Exception.GetObjectData
.The following types are marked
[EditorBrowsable(EditorBrowsableState.Never)]
, but they are not obsoleted. Marking them with the[EditorBrowsable(EditorBrowsableState.Never)]
annotation will hide them from within the Visual Studio IDE. However, they can still be referenced by .NET 8 apps, and callers will not observe a compilation warning or error when referencing these types.System.NonSerializedAttribute
System.SerializableAttribute
Associated WorkItem - 91242
The text was updated successfully, but these errors were encountered: