Skip to content

Commit 1aef51e

Browse files
authored
[DOCSP-26327] GUID Serialization (#44)
* wip * wip * first draft * first draft * add to TOC * refinement * implement some feedback * more feedback * broken link
1 parent 0b68777 commit 1aef51e

File tree

2 files changed

+187
-1
lines changed

2 files changed

+187
-1
lines changed

source/fundamentals/data-formats.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ Data Formats
1010
:caption: Data Formats
1111

1212
/fundamentals/data-formats/bson
13-
/fundamentals/data-formats/poco
13+
/fundamentals/data-formats/poco
14+
/fundamentals/data-formats/guid-serialization
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
.. _csharp-guids:
2+
3+
==================
4+
GUID Serialization
5+
==================
6+
7+
.. default-domain:: mongodb
8+
9+
.. contents:: On this page
10+
:local:
11+
:backlinks: none
12+
:depth: 2
13+
:class: singlecol
14+
15+
Overview
16+
--------
17+
18+
In this guide, you can learn how to serialize **globally unique identifiers**
19+
(`GUIDs <https://learn.microsoft.com/en-us/dynamicsax-2012/developer/guids>`__),
20+
also known as **universally unique identifiers** (UUIDs).
21+
22+
A GUID is a 16-byte integer that you can use as a unique ID for a MongoDB document.
23+
Originally, GUIDs in MongoDB were represented as ``BsonBinaryData`` values of subtype 3.
24+
Subtype 3 did not standardize the byte order during serialization, which led to
25+
inconsistent serialization across MongoDB drivers.
26+
To standardize the byte order and ensure consistent serialization across drivers, we
27+
created ``BsonBinaryData`` subtype 4.
28+
29+
.. note::
30+
31+
Use ``BsonBinaryData`` subtype 4 for all new GUIDs.
32+
33+
GuidRepresentationMode
34+
----------------------
35+
36+
In many MongoDB collections, all GUID fields use the same subtype of ``BsonBinaryData``.
37+
Some older collections, however, may contain some GUID fields that
38+
use subtype 3 and others that use subtype 4.
39+
To ensure that the driver serializes and deserializes all GUIDs correctly,
40+
you should set the ``BsonDefaults.GuidRepresentationMode`` property to one of the
41+
following ``GuidRepresentationMode`` values:
42+
43+
V2
44+
~~
45+
46+
``GuidRepresentationMode.V2`` assumes that all GUIDs in a collection use the same
47+
``BsonBinaryData`` subtype. In this mode, GUID representation is
48+
controlled by the reader or writer, not the serializer.
49+
50+
``V2`` is the default ``GuidRepresentationMode``.
51+
52+
.. note::
53+
54+
When version 3 of the {+driver-short+} is released, support for ``GuidRepresentationMode.V2``
55+
will be removed from the driver and ``V3`` will become the default.
56+
57+
V3
58+
~~
59+
60+
``GuidRepresentationMode.V3`` allows documents in the same collection to use different
61+
GUID formats.
62+
In this mode, GUID representation is controlled at the property level by configuring the
63+
serializer for each property.
64+
65+
To use ``GuidRepresentationMode.V3``, run the following line of code. You should run this
66+
code during the bootstrapping phase of your application, before creating
67+
a ``MongoClient`` object.
68+
69+
.. code-block:: csharp
70+
71+
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
72+
73+
Running in ``V3`` mode changes the behavior of the driver in the following ways:
74+
75+
- The ``BsonBinaryReader.ReadBinaryData()`` method ignores ``readerSettings.GuidRepresentation``
76+
- The ``BsonBinaryWriter.WriteBinaryData()`` method ignores ``writerSettings.GuidRepresentation``
77+
- The ``JsonReader.ReadBinaryData()`` method ignores ``readerSettings.GuidRepresentation``
78+
- ``JsonWriter`` ignores ``writerSettings.GuidRepresentation``
79+
- Calling the ``BsonBinaryData.ToGuid()`` method without the ``GuidRepresentation``
80+
parameter works only on GUIDs of subtype 4.
81+
82+
.. note::
83+
84+
You can't use both ``GuidRepresentationMode.V2`` and ``GuidRepresentationMode.V3``
85+
in a single application.
86+
87+
Serializing GUIDs in V3
88+
-----------------------
89+
90+
``GuidRepresentationMode.V3`` handles GUID serialization at the level of individual
91+
properties. This mode is more flexible than ``V2``, but it also means you must ensure that
92+
each GUID field is serialized and deserialized correctly.
93+
94+
If you're using the {+driver-short+} to :ref:`automap your {+language+} classes to document schemas <csharp-class-mapping>`,
95+
you can use the ``BsonGuidRepresentation`` attribute on a GUID property
96+
to specify the representation:
97+
98+
.. code-block:: csharp
99+
100+
public class Widget
101+
{
102+
public int Id { get; set; }
103+
104+
[BsonGuidRepresentation(GuidRepresentation.Standard)]
105+
public Guid G { get; set; }
106+
}
107+
108+
.. note::
109+
110+
``GuidRepresentation.Standard`` is equivalent to ``BsonBinaryData`` subtype 4.
111+
Other GUID representations in the {+driver-short+}, such as ``CSharpLegacy``,
112+
``JavaLegacy``, and ``PythonLegacy``, are equivalent to subtype 3 but use
113+
different byte orders.
114+
115+
If you're writing your own serialization code, you can use the
116+
``GuidSerializer`` class to serialize and deserialize individual GUID values to and
117+
from BSON fields. To ensure that the driver handles GUIDs correctly, use the
118+
``GuidRepresentation`` parameter when you construct a ``GuidSerializer``.
119+
120+
The following code sample creates an instance of ``GuidSerializer``
121+
for serializing GUID representations of subtype 4:
122+
123+
.. code-block::
124+
125+
var guidSerializer = new GuidSerializer(GuidRepresentation.Standard);
126+
127+
If most of your GUIDs use the same representation, you can register a ``GuidSerializer``
128+
globally. To create and register a ``GuidSerializer``, run the following code early
129+
in your application, such as during the bootstrapping phase:
130+
131+
.. code-block:: csharp
132+
133+
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
134+
135+
.. tip::
136+
137+
When you're working with two subtypes, you can combine a global serializer with the
138+
``BsonGuidRepresentation`` property attribute. For example, you can register a global
139+
serializer for the most commonly used GUID subtype, then use the ``BsonGuidRepresentation``
140+
attribute to denote any GUID properties of another subtype.
141+
142+
Serializing Objects in V3
143+
-------------------------
144+
145+
You can use an ``ObjectSerializer`` to serialize hierarchical objects to subdocuments.
146+
To ensure that GUIDs in these objects are serialized and deserialized correctly when using
147+
``V3``, you should select the correct GUID representation when constructing your
148+
``ObjectSerializer``.
149+
150+
The following code sample shows how to
151+
create an ``ObjectSerializer`` for a GUID representation of subtype 4:
152+
153+
.. code-block:: csharp
154+
155+
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
156+
var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard);
157+
158+
If your application relies on an ``ObjectSerializer`` to serialize any GUIDs, you
159+
must also register the serializer early in your application, such as during the
160+
bootstrapping phase. The serializer that you
161+
register will be used globally whenever an object serializer is needed and has not
162+
been otherwise specified.
163+
164+
To register your ``ObjectSerializer``, pass it to the ``BsonSerializer.RegisterSerializer()``
165+
method:
166+
167+
.. code-block:: csharp
168+
:emphasize-lines: 3
169+
170+
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
171+
var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard);
172+
BsonSerializer.RegisterSerializer(objectSerializer);
173+
174+
Additional Information
175+
----------------------
176+
177+
To learn more about any of the methods or types discussed in this
178+
guide, see the following API documentation:
179+
180+
- `BsonBinaryData <{+api-root+}/T_MongoDB_Bson_BsonBinaryData.htm>`__
181+
- `GuidRepresentationMode <{+api-root+}/T_MongoDB_Bson_GuidRepresentationMode.htm>`__
182+
- `BsonGuidRepresentation <{+api-root+}/T_MongoDB_Bson_Serialization_Attributes_BsonGuidRepresentationAttribute.htm>`__
183+
- `GuidSerializer <{+api-root+}/T_MongoDB_Bson_Serialization_Serializers_GuidSerializer.htm>`__
184+
- `ObjectSerializer <{+api-root+}/T_MongoDB_Bson_Serialization_Serializers_ObjectSerializer.htm>`__
185+

0 commit comments

Comments
 (0)