Skip to content

Commit 0faf20f

Browse files
committed
add step-by-step descriptions
1 parent 4e76345 commit 0faf20f

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

docs/standard/serialization/binaryformatter-migration-guide/migration-to-data-contract-serializer.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ helpviewer_keywords:
1717

1818
The .NET base class libraries provide two XML serializers: [XmlSerializer](../introducing-xml-serialization.md) and [DataContractSerializer](../../../fundamentals/runtime-libraries/system-runtime-serialization-datacontractserializer.md). There are some subtle differences between these two, but for the purpose of the migration, this section focuses only on `DataContractSerializer`. Why? Because it **fully supports the serialization programming model that was used by `BinaryFormatter`**. All the types that are already marked as `[Serializable]` or implement `ISerializable` can be serialized with `DataContractSerializer`. Where is the catch? Known types must be specified up front (that's why it's secure). You need to know them and be able to get the `Type`, **even for private types**.
1919

20+
21+
It's not required to specify most popular collections or primitive types like `string` or `DateTime` (the serializer has its own default allowlist), but there are exceptions like `DateTimeOffset`. For more information about the supported types, see [Types supported by the data contract serializer](../../../framework/wcf/feature-details/types-supported-by-the-data-contract-serializer.md).
22+
23+
[Partial trust](../../../framework/wcf/feature-details/partial-trust.md) is a .NET Framework feature that wasn't ported to .NET (Core). If your code runs on .NET Framework and uses this feature, read about the [limitations](../../../framework/wcf/feature-details/types-supported-by-the-data-contract-serializer.md#limitations-of-using-certain-types-in-partial-trust-mode) that might apply to such a scenario.
24+
25+
## Step by step migration
26+
27+
1. Find all the usages of `BinaryFormatter`.
28+
2. Ensure that the serialization code paths are covered with tests, so you can verify your changes and avoid introducing bugs.
29+
3. You don't need to install any pacakges, as `DataContractSerializer` is part of the .NET shared framework.
30+
4. Find all the types that are being serialized with `BinaryFormatter`. You don't need to modify any of them, but you may need to list them via `knownTypes` argument of the `DataContractSerializer` ctor.
31+
5. Replace the usage of `BinaryFormatter` with `DataContractSerializer`.
32+
2033
```csharp
2134
DataContractSerializer serializer = new(
2235
type: input.GetType(),
@@ -26,7 +39,3 @@ DataContractSerializer serializer = new(
2639
typeof(MyType2)
2740
});
2841
```
29-
30-
It's not required to specify most popular collections or primitive types like `string` or `DateTime` (the serializer has its own default allowlist), but there are exceptions like `DateTimeOffset`. For more information about the supported types, see [Types supported by the data contract serializer](../../../framework/wcf/feature-details/types-supported-by-the-data-contract-serializer.md).
31-
32-
[Partial trust](../../../framework/wcf/feature-details/partial-trust.md) is a .NET Framework feature that wasn't ported to .NET (Core). If your code runs on .NET Framework and uses this feature, read about the [limitations](../../../framework/wcf/feature-details/types-supported-by-the-data-contract-serializer.md#limitations-of-using-certain-types-in-partial-trust-mode) that might apply to such a scenario.

docs/standard/serialization/binaryformatter-migration-guide/migration-to-protobuf-net.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,44 @@ helpviewer_keywords:
1616

1717
- By default, both public and non-public types are serializable. Every type needs to provide a parameterless constructor.
1818
- protobuf-net requires each serializable type to be annotated with `[ProtoContract]` attribute.
19-
- Every serializable non-static field and a property needs to be annotated with `[ProtoMember(int tag)]` attribute. The member names aren't encoded in the data. Instead, the users must pick an integer to identify each member.
19+
- Every serializable non-static field and a property needs to be annotated with `[ProtoMember(int identifier)]` attribute. The member names aren't encoded in the data. Instead, the users must pick an integer to identify each member.
2020
- [Inheritance](https://github.com/protobuf-net/protobuf-net?tab=readme-ov-file#inheritance) must be explicitly declared via `[ProtoInclude(...)]` attribute on each type with known subtypes.
2121
- Read-only fields are supported by default.
22+
23+
## Step by step migration
24+
25+
1. Find all the usages of `BinaryFormatter`.
26+
2. Ensure that the serialization code paths are covered with tests, so you can verify your changes and avoid introducing bugs.
27+
3. Install `protobuf-net` package.
28+
4. Find all the types that are being serialized with `BinaryFormatter`.
29+
5. For types that you can modify:
30+
- Annotate with `[ProtoContract]` attribute all types that are marked with `[Serializable]` or implement the `ISerializable` interface. If these types are not exposed to other apps (example: you are writing a library) that may use different serializers like `DataContractSerializer`, you can remove the `[Serializable]` and `ISerializable` annotations.
31+
- For derived types, apply `[ProtoInclude(...)]` to their base types (see the example below).
32+
- For every type that declares any constructor that accepts parameters, add a parameterless constructor. Leave a comment that explains the protobuf-net requirement (so nobody removes it by accident).
33+
- Mark all the members (fields and properties) that you wish to serialize with `[ProtoMember(int identifier)]`. All identifiers must be unique within a single type, but the same numbers can be re-used in sub-types if inheritance is enabled.
34+
35+
```diff
36+
-[Serializable]
37+
+[ProtoContract]
38+
+[ProtoInclude(2, typeof(Point2D))]
39+
public class Point1D
40+
{
41+
+ [ProtoMember(1)]
42+
public int X { get; set; }
43+
}
44+
45+
-[Serializable]
46+
+[ProtoContract]
47+
public class Point2D : Point1D
48+
{
49+
+ [ProtoMember(2)]
50+
public int Y { get; set; }
51+
}
52+
```
53+
54+
6. For types that you can't modify:
55+
- For types provided by the .NET itself, you can use `ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)` API to check if they are natively supported by protobuf-net.
56+
- You can create dedicated data transfer objects (DTO) and map them accordingly (you could use implicit cast operator for that).
57+
58+
- Use the `RuntimeTypeModel` API to define everything that the attributes allow for.
59+
7. Replace the usage of `BinaryFormatter` with `ProtoBuf.Serializer`.

0 commit comments

Comments
 (0)