From 6a6b67e571a86c4717cfa51ae13539cbcf02421b Mon Sep 17 00:00:00 2001 From: rstam Date: Thu, 30 Jul 2020 07:58:33 -0700 Subject: [PATCH] CSHARP-2994: Write reference documentation for new V3 GuidRepresentationMode. --- .../bson/guidserialization/background.md | 32 ++++++++++++ .../guidrepresentationmode.md | 49 +++++++++++++++++ .../guidrepresentationmode/v2mode.md | 40 ++++++++++++++ .../guidrepresentationmode/v3mode.md | 27 ++++++++++ .../reference/bson/guidserialization/index.md | 22 ++++++++ .../guidserializerchanges.md | 52 +++++++++++++++++++ .../objectserializerchanges.md | 36 +++++++++++++ .../serializerchanges/serializerchanges.md | 17 ++++++ .../reference/content/reference/bson/index.md | 3 +- 9 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 Docs/reference/content/reference/bson/guidserialization/background.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/guidrepresentationmode.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v2mode.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v3mode.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/index.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/serializerchanges/guidserializerchanges.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/serializerchanges/objectserializerchanges.md create mode 100644 Docs/reference/content/reference/bson/guidserialization/serializerchanges/serializerchanges.md diff --git a/Docs/reference/content/reference/bson/guidserialization/background.md b/Docs/reference/content/reference/bson/guidserialization/background.md new file mode 100644 index 00000000000..ac8347e80c2 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/background.md @@ -0,0 +1,32 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "Background" +[menu.main] + parent = "GuidSerialization" + identifier = "GuidSerializationBackground" + weight = 10 + pre = "" ++++ + +## Background information + +Guids were originally represented in BSON as BsonBinaryData values of subtype 3. Unfortunately, different drivers +inadvertently used different byte orders when converting a Guid to a 16 byte binary value. To standardize on a +single canonical representation BsonBinaryData subtype 4 was created with a well defined byte order. + +The C# driver's support for Guids was originally based on the premise that all Guids in a single collection must +be represented the same way (i.e. using the same BsonBinaryData sub type and byte order). In order to accomplish this +the representation of Guids is enforced at the BSON reader and writer levels (because a single reader or writer is +used to read or write an entire document from or to the collection). + +However, this original premise has not stood the test of time. + +The first issue we ran into was that the server +started returning UUIDs (i.e. Guids) in metadata using standard subtype 4. If a collection was configured to use +subtype 3 (which it usually was since that is the default) the driver could not deserialize the Guids in the metadata +without throwing an exception. We worked around this by temporarily reconfiguring the BSON reader while reading the metadata. + +The second issue is that the original premise was too strict. There are valid reasons why a single collection might +have a mix of Guid representations, and we need to allow that. + diff --git a/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/guidrepresentationmode.md b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/guidrepresentationmode.md new file mode 100644 index 00000000000..681ed197a52 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/guidrepresentationmode.md @@ -0,0 +1,49 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "GuidRepresentationMode" +[menu.main] + parent = "GuidSerialization" + identifier = "GuidRepresentationMode" + weight = 10 + pre = "" ++++ + +## GuidRepresentationMode + +If we just abruptly changed the way the driver serialized Guids that would be a breaking change. In order to help applications +migrate in an orderly fashion to the new way of handling Guids we have introduced a configurable `GuidRepresentationMode`. +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 +will handle Guids in the new way. An application can opt-in to V3 mode to transition to the new way Guids are handled. +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 +V3 will be the default mode (and support for V2 mode will be removed). + +### GuidRepresentationMode == V2 (Deprecated) + +In V2 mode the central principle is that all Guids in a collection must be represented the same way. In order to enforce +this the representation of Guids is not controlled at the individual serializer level, but rather at the reader/writer +level since the same reader/writer is used to read/write an entire document. + +Read more about V2 mode [here]({{< relref "reference\bson\guidserialization\guidrepresentationmode\v2mode.md" >}}). + +### GuidRepresentationMode == V3 + +In V3 mode the central principle is that the representation of Guids is controlled at the level of each individual +property by configuring the serializer for that property. The recommendation is that all Guids in a +collection be represented uniformly using the standard BsonBinaryData subtype 4, but when working with historical +data it is acceptable for different Guid fields in the same document to be represented differently. + +Read more about V3 mode [here]({{< relref "reference\bson\guidserialization\guidrepresentationmode\v3mode.md" >}}). + +### Opting in to V3 GuidRepresentationMode + +An application must choose to use either the original V2 GuidRepresentationMode or the new V3 GuidRepresentationMode. It is +not possible to mix use of both modes in the same application. + +If you want to use V2 mode you don't need to do anything because V2 is still the default. + +If you want to use V3 mode execute the following line of code as early as possible in your application: + +```csharp +BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; +``` diff --git a/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v2mode.md b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v2mode.md new file mode 100644 index 00000000000..a7299770a77 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v2mode.md @@ -0,0 +1,40 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "V2 mode" +[menu.main] + parent = "GuidRepresentationMode" + identifier = "GuidRepresentationModeV2" + weight = 20 + pre = "" ++++ + +## V2 GuidRepresentationMode (Deprecated) + +In V2 mode the central principle is that all Guids in a collection must be represented the same way. In order to enforce +this the representation of Guids is not controlled at the individual serializer level, but rather at the reader/writer +level since the same reader/writer is used to read/write an entire document. + +All of the following properties and methods are only relevant to V2 mode and are now deprecated: + +* BsonDefaults GuidRepresentation property +* BsonBinaryData implicit conversion to or from Guid +* BsonBinaryData constructor taking a Guid (without a GuidRepresentation) +* BsonBinaryData constructor taking (byte[], BsonBinarySubType, GuidRepresentation) +* BsonBinaryData GuidRepresentation property +* BsonValue implicit conversion from Guid or Guid? (Nullable\) +* BsonDocumentReaderSettings constructor taking a GuidRepresentation +* BsonDocumentWriterSettings constructor taking a GuidRepresentation +* BsonReaderSettings GuidRepresentation property +* BsonWriterSettings GuidRepresentation property +* IBsonReaderExtentions ReadBinaryDataWithGuidRepresentationUnspecified extension method +* MongoClientSettings GuidRepresentation property +* MongoCollectionSettings GuidRepresentation property +* MongoDatabaseSettings GuidRepresentation property +* MongoDefaults GuidRepresentation property +* MongoUrl GuidRepresentation property +* MongoUrlBuilder GuidRepresentation property +* MongoGridFSSettings GuidRepresentation property + +Note: the BsonDefaults GuidRepresentationMode property is itself deprecated even though it is new because it is only +intended to be use during the transition period and will be removed when support for V2 mode is removed. diff --git a/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v3mode.md b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v3mode.md new file mode 100644 index 00000000000..84e6b8a52e8 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/guidrepresentationmode/v3mode.md @@ -0,0 +1,27 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "V3 mode" +[menu.main] + parent = "GuidRepresentationMode" + identifier = "GuidRepresentationModeV3" + weight = 20 + pre = "" ++++ + +## V3 GuidRepresentationMode + +In V3 mode the central principle is that the representation of Guids is controlled at the level of each individual +property of a document by configuring the serializer for that property. The recommendation is that all Guids in a +collection be represented uniformly using the standard BsonBinaryData subtype 4, but when working with historical +data it is acceptable for different Guid fields in the same document to be represented differently. + +The following existing methods behave differently in V3 mode: + +* BsonBinaryReader.ReadBinaryData method ignores readerSettings.GuidRepresentation +* BsonBinaryWriter.WriteBinaryData method ignores writerSettings.GuidRepresentation +* JsonReader ReadBinaryData method ignores readerSettings.GuidRepresentation +* JsonWriter ignores writerSettings.GuidRepresentation +* BsonBinaryData ToGuid without GuidRepresentation argument is only valid for sub type 4 + + diff --git a/Docs/reference/content/reference/bson/guidserialization/index.md b/Docs/reference/content/reference/bson/guidserialization/index.md new file mode 100644 index 00000000000..87c763b9281 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/index.md @@ -0,0 +1,22 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "Guid Serialization" +[menu.main] + parent = "BSON" + identifier = "GuidSerialization" + weight = 35 + pre = "" ++++ + +# Guid serialization + +We are making changes to how Guids will be serialized in the future. For the time being the driver will +continue to serialize Guids as it has in the past, in order to not break backward compatibility. You +can opt-in to the new way of serializing Guids by setting the GuidRepresentationMode to V3. + +The folowing sections contain more information: + +* - [Background]({{< relref "reference\bson\guidserialization\background.md" >}}) +* - [GuidRepresentationMode]({{< relref "reference\bson\guidserialization\guidrepresentationmode\guidrepresentationmode.md" >}}) +* - [Serializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\serializerchanges.md" >}}) diff --git a/Docs/reference/content/reference/bson/guidserialization/serializerchanges/guidserializerchanges.md b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/guidserializerchanges.md new file mode 100644 index 00000000000..8800f12fcc2 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/guidserializerchanges.md @@ -0,0 +1,52 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "GuidSerializer changes" +[menu.main] + parent = "GuidSerializationSerializerChanges" + identifier = "GuidSerializerChanges" + weight = 20 + pre = "" ++++ + +# GuidSerializer changes + +Some small changes have been made to the GuidSerializer to allow the GuidRepresentation it uses to be configurable at the serializer level. + +## GuidRepresentation constructor argument and property + +A new constructor has been added that allows you to configure the desired GuidRepresentation when instantiating an instance of +the GuidSerializer. Calling the constructor that takes a GuidRepresentation property implies a BsonType representation of Binary. + +For example: + +```csharp +var guidSerializer = new GuidSerializer(GuidRepresentation.Standard); +``` + +If you want to use the Standard GuidRepresentation globally you can register a properly configured GuidSerializer early in your code: + +```csharp +BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)); +``` + +## BsonGuidRepresentation attribute + +In V3 GuidRepresentationMode you must explicitly specify the GuidRepresentation you want used for every Guid property. If you are +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. + +For example: + +```csharp +public class C +{ + public int Id { get; set; } + + [BsonGuidRepresentation(GuidRepresentation.Standard)] + public Guid G { get; set; } +} +``` + +If most of your Guids use the same representation and only a few use a different representation, you could alternatively register +a global GuidSerializer (as shown above) for the most commonly used representation, and only use the BsonGuidRepresentation attribute +to mark the ones that use a different representation. \ No newline at end of file diff --git a/Docs/reference/content/reference/bson/guidserialization/serializerchanges/objectserializerchanges.md b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/objectserializerchanges.md new file mode 100644 index 00000000000..6f879226c97 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/objectserializerchanges.md @@ -0,0 +1,36 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "ObjectSerializer changes" +[menu.main] + parent = "GuidSerializationSerializerChanges" + identifier = "ObjectSerializerChanges" + weight = 20 + pre = "" ++++ + +# ObjectSerializer changes + +Some small changes have been made to the ObjectSerializer to allow the GuidRepresentation it uses to be configurable at the serializer level. + +## GuidRepresentation constructor argument and property + +A new constructor has been added that allows you to configure the desired GuidRepresentation when instantiating an instance of +the ObjectSerializer. + +For example: + +```csharp +var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); +var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard); +``` + +In V3 GuidRepresentationMode, if your application relies on the ObjectSerializer to serialize any Guids you must register +an object serializer that you have configured the way you want. This must be done early in your application and this object +serializer will be globally used whenever an object serializer is needed and has not been otherwise specified. + +```csharp +var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); +var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard); +BsonSerializer.RegisterSerializer(objectSerializer); +``` diff --git a/Docs/reference/content/reference/bson/guidserialization/serializerchanges/serializerchanges.md b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/serializerchanges.md new file mode 100644 index 00000000000..52388014ca6 --- /dev/null +++ b/Docs/reference/content/reference/bson/guidserialization/serializerchanges/serializerchanges.md @@ -0,0 +1,17 @@ ++++ +date = "2020-07-23T00:00:00Z" +draft = false +title = "Serializer changes" +[menu.main] + parent = "GuidSerialization" + identifier = "GuidSerializationSerializerChanges" + weight = 10 + pre = "" ++++ + +# Serializer changes + +The following sections describe changes to the two serializers to handle Guids differently: + +* - [GuidSerializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\guidserializerchanges.md" >}}) +* - [ObjectSerializer changes]({{< relref "reference\bson\guidserialization\serializerchanges\objectserializerchanges.md" >}}) diff --git a/Docs/reference/content/reference/bson/index.md b/Docs/reference/content/reference/bson/index.md index 2232b692cd3..82eac704e97 100644 --- a/Docs/reference/content/reference/bson/index.md +++ b/Docs/reference/content/reference/bson/index.md @@ -16,4 +16,5 @@ The MongoDB.Bson library handles [BSON](http://bsonspec.org) and [JSON](http://j - [Reading and Writing BSON/JSON]({{< relref "reference\bson\bson.md" >}}) - [BsonDocument]({{< relref "reference\bson\bson_document.md" >}}) - [Serialization]({{< relref "reference\bson\serialization.md" >}}) -- [Mapping Classes]({{< relref "reference\bson\mapping\index.md" >}}) \ No newline at end of file +- [Guid Serialization]({{< relref "reference\bson\guidserialization\index.md" >}}) +- [Mapping Classes]({{< relref "reference\bson\mapping\index.md" >}})