Skip to content

Commit 6a6b67e

Browse files
committed
CSHARP-2994: Write reference documentation for new V3 GuidRepresentationMode.
1 parent 9ac03cf commit 6a6b67e

File tree

9 files changed

+277
-1
lines changed

9 files changed

+277
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "Background"
5+
[menu.main]
6+
parent = "GuidSerialization"
7+
identifier = "GuidSerializationBackground"
8+
weight = 10
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
## Background information
13+
14+
Guids were originally represented in BSON as BsonBinaryData values of subtype 3. Unfortunately, different drivers
15+
inadvertently used different byte orders when converting a Guid to a 16 byte binary value. To standardize on a
16+
single canonical representation BsonBinaryData subtype 4 was created with a well defined byte order.
17+
18+
The C# driver's support for Guids was originally based on the premise that all Guids in a single collection must
19+
be represented the same way (i.e. using the same BsonBinaryData sub type and byte order). In order to accomplish this
20+
the representation of Guids is enforced at the BSON reader and writer levels (because a single reader or writer is
21+
used to read or write an entire document from or to the collection).
22+
23+
However, this original premise has not stood the test of time.
24+
25+
The first issue we ran into was that the server
26+
started returning UUIDs (i.e. Guids) in metadata using standard subtype 4. If a collection was configured to use
27+
subtype 3 (which it usually was since that is the default) the driver could not deserialize the Guids in the metadata
28+
without throwing an exception. We worked around this by temporarily reconfiguring the BSON reader while reading the metadata.
29+
30+
The second issue is that the original premise was too strict. There are valid reasons why a single collection might
31+
have a mix of Guid representations, and we need to allow that.
32+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "GuidRepresentationMode"
5+
[menu.main]
6+
parent = "GuidSerialization"
7+
identifier = "GuidRepresentationMode"
8+
weight = 10
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
## GuidRepresentationMode
13+
14+
If we just abruptly changed the way the driver serialized Guids that would be a breaking change. In order to help applications
15+
migrate in an orderly fashion to the new way of handling Guids we have introduced a configurable `GuidRepresentationMode`.
16+
In V2 mode the driver will handle Guids the same way that the v2.x versions have in the past. In V3 mode the driver
17+
will handle Guids in the new way. An application can opt-in to V3 mode to transition to the new way Guids are handled.
18+
In the v2.x versions of the driver V2 is the default mode but V3 mode is supported. In future v3.x versions of the driver
19+
V3 will be the default mode (and support for V2 mode will be removed).
20+
21+
### GuidRepresentationMode == V2 (Deprecated)
22+
23+
In V2 mode the central principle is that all Guids in a collection must be represented the same way. In order to enforce
24+
this the representation of Guids is not controlled at the individual serializer level, but rather at the reader/writer
25+
level since the same reader/writer is used to read/write an entire document.
26+
27+
Read more about V2 mode [here]({{< relref "reference\bson\guidserialization\guidrepresentationmode\v2mode.md" >}}).
28+
29+
### GuidRepresentationMode == V3
30+
31+
In V3 mode the central principle is that the representation of Guids is controlled at the level of each individual
32+
property by configuring the serializer for that property. The recommendation is that all Guids in a
33+
collection be represented uniformly using the standard BsonBinaryData subtype 4, but when working with historical
34+
data it is acceptable for different Guid fields in the same document to be represented differently.
35+
36+
Read more about V3 mode [here]({{< relref "reference\bson\guidserialization\guidrepresentationmode\v3mode.md" >}}).
37+
38+
### Opting in to V3 GuidRepresentationMode
39+
40+
An application must choose to use either the original V2 GuidRepresentationMode or the new V3 GuidRepresentationMode. It is
41+
not possible to mix use of both modes in the same application.
42+
43+
If you want to use V2 mode you don't need to do anything because V2 is still the default.
44+
45+
If you want to use V3 mode execute the following line of code as early as possible in your application:
46+
47+
```csharp
48+
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
49+
```
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "V2 mode"
5+
[menu.main]
6+
parent = "GuidRepresentationMode"
7+
identifier = "GuidRepresentationModeV2"
8+
weight = 20
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
## V2 GuidRepresentationMode (Deprecated)
13+
14+
In V2 mode the central principle is that all Guids in a collection must be represented the same way. In order to enforce
15+
this the representation of Guids is not controlled at the individual serializer level, but rather at the reader/writer
16+
level since the same reader/writer is used to read/write an entire document.
17+
18+
All of the following properties and methods are only relevant to V2 mode and are now deprecated:
19+
20+
* BsonDefaults GuidRepresentation property
21+
* BsonBinaryData implicit conversion to or from Guid
22+
* BsonBinaryData constructor taking a Guid (without a GuidRepresentation)
23+
* BsonBinaryData constructor taking (byte[], BsonBinarySubType, GuidRepresentation)
24+
* BsonBinaryData GuidRepresentation property
25+
* BsonValue implicit conversion from Guid or Guid? (Nullable\<Guid>)
26+
* BsonDocumentReaderSettings constructor taking a GuidRepresentation
27+
* BsonDocumentWriterSettings constructor taking a GuidRepresentation
28+
* BsonReaderSettings GuidRepresentation property
29+
* BsonWriterSettings GuidRepresentation property
30+
* IBsonReaderExtentions ReadBinaryDataWithGuidRepresentationUnspecified extension method
31+
* MongoClientSettings GuidRepresentation property
32+
* MongoCollectionSettings GuidRepresentation property
33+
* MongoDatabaseSettings GuidRepresentation property
34+
* MongoDefaults GuidRepresentation property
35+
* MongoUrl GuidRepresentation property
36+
* MongoUrlBuilder GuidRepresentation property
37+
* MongoGridFSSettings GuidRepresentation property
38+
39+
Note: the BsonDefaults GuidRepresentationMode property is itself deprecated even though it is new because it is only
40+
intended to be use during the transition period and will be removed when support for V2 mode is removed.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "V3 mode"
5+
[menu.main]
6+
parent = "GuidRepresentationMode"
7+
identifier = "GuidRepresentationModeV3"
8+
weight = 20
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
## V3 GuidRepresentationMode
13+
14+
In V3 mode the central principle is that the representation of Guids is controlled at the level of each individual
15+
property of a document by configuring the serializer for that property. The recommendation is that all Guids in a
16+
collection be represented uniformly using the standard BsonBinaryData subtype 4, but when working with historical
17+
data it is acceptable for different Guid fields in the same document to be represented differently.
18+
19+
The following existing methods behave differently in V3 mode:
20+
21+
* BsonBinaryReader.ReadBinaryData method ignores readerSettings.GuidRepresentation
22+
* BsonBinaryWriter.WriteBinaryData method ignores writerSettings.GuidRepresentation
23+
* JsonReader ReadBinaryData method ignores readerSettings.GuidRepresentation
24+
* JsonWriter ignores writerSettings.GuidRepresentation
25+
* BsonBinaryData ToGuid without GuidRepresentation argument is only valid for sub type 4
26+
27+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "Guid Serialization"
5+
[menu.main]
6+
parent = "BSON"
7+
identifier = "GuidSerialization"
8+
weight = 35
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
# Guid serialization
13+
14+
We are making changes to how Guids will be serialized in the future. For the time being the driver will
15+
continue to serialize Guids as it has in the past, in order to not break backward compatibility. You
16+
can opt-in to the new way of serializing Guids by setting the GuidRepresentationMode to V3.
17+
18+
The folowing sections contain more information:
19+
20+
* - [Background]({{< relref "reference\bson\guidserialization\background.md" >}})
21+
* - [GuidRepresentationMode]({{< relref "reference\bson\guidserialization\guidrepresentationmode\guidrepresentationmode.md" >}})
22+
* - [Serializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\serializerchanges.md" >}})
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "GuidSerializer changes"
5+
[menu.main]
6+
parent = "GuidSerializationSerializerChanges"
7+
identifier = "GuidSerializerChanges"
8+
weight = 20
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
# GuidSerializer changes
13+
14+
Some small changes have been made to the GuidSerializer to allow the GuidRepresentation it uses to be configurable at the serializer level.
15+
16+
## GuidRepresentation constructor argument and property
17+
18+
A new constructor has been added that allows you to configure the desired GuidRepresentation when instantiating an instance of
19+
the GuidSerializer. Calling the constructor that takes a GuidRepresentation property implies a BsonType representation of Binary.
20+
21+
For example:
22+
23+
```csharp
24+
var guidSerializer = new GuidSerializer(GuidRepresentation.Standard);
25+
```
26+
27+
If you want to use the Standard GuidRepresentation globally you can register a properly configured GuidSerializer early in your code:
28+
29+
```csharp
30+
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
31+
```
32+
33+
## BsonGuidRepresentation attribute
34+
35+
In V3 GuidRepresentationMode you must explicitly specify the GuidRepresentation you want used for every Guid property. If you are
36+
relying on the driver's auto mapping to map C# classes to document schemas you may use the new BsonGuidRepresentation attribute to specify the desired representation.
37+
38+
For example:
39+
40+
```csharp
41+
public class C
42+
{
43+
public int Id { get; set; }
44+
45+
[BsonGuidRepresentation(GuidRepresentation.Standard)]
46+
public Guid G { get; set; }
47+
}
48+
```
49+
50+
If most of your Guids use the same representation and only a few use a different representation, you could alternatively register
51+
a global GuidSerializer (as shown above) for the most commonly used representation, and only use the BsonGuidRepresentation attribute
52+
to mark the ones that use a different representation.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "ObjectSerializer changes"
5+
[menu.main]
6+
parent = "GuidSerializationSerializerChanges"
7+
identifier = "ObjectSerializerChanges"
8+
weight = 20
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
# ObjectSerializer changes
13+
14+
Some small changes have been made to the ObjectSerializer to allow the GuidRepresentation it uses to be configurable at the serializer level.
15+
16+
## GuidRepresentation constructor argument and property
17+
18+
A new constructor has been added that allows you to configure the desired GuidRepresentation when instantiating an instance of
19+
the ObjectSerializer.
20+
21+
For example:
22+
23+
```csharp
24+
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
25+
var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard);
26+
```
27+
28+
In V3 GuidRepresentationMode, if your application relies on the ObjectSerializer to serialize any Guids you must register
29+
an object serializer that you have configured the way you want. This must be done early in your application and this object
30+
serializer will be globally used whenever an object serializer is needed and has not been otherwise specified.
31+
32+
```csharp
33+
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
34+
var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard);
35+
BsonSerializer.RegisterSerializer(objectSerializer);
36+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
+++
2+
date = "2020-07-23T00:00:00Z"
3+
draft = false
4+
title = "Serializer changes"
5+
[menu.main]
6+
parent = "GuidSerialization"
7+
identifier = "GuidSerializationSerializerChanges"
8+
weight = 10
9+
pre = "<i class='fa'></i>"
10+
+++
11+
12+
# Serializer changes
13+
14+
The following sections describe changes to the two serializers to handle Guids differently:
15+
16+
* - [GuidSerializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\guidserializerchanges.md" >}})
17+
* - [ObjectSerializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\objectserializerchanges.md" >}})

Docs/reference/content/reference/bson/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ The MongoDB.Bson library handles [BSON](http://bsonspec.org) and [JSON](http://j
1616
- [Reading and Writing BSON/JSON]({{< relref "reference\bson\bson.md" >}})
1717
- [BsonDocument]({{< relref "reference\bson\bson_document.md" >}})
1818
- [Serialization]({{< relref "reference\bson\serialization.md" >}})
19-
- [Mapping Classes]({{< relref "reference\bson\mapping\index.md" >}})
19+
- [Guid Serialization]({{< relref "reference\bson\guidserialization\index.md" >}})
20+
- [Mapping Classes]({{< relref "reference\bson\mapping\index.md" >}})

0 commit comments

Comments
 (0)