C# decode and encode guids in mongosh

Hi,

we are currently working on a new project and use MongoDB as data store. In a lot of the tables we are using GUIDs as primary keys and within our data model. Everything works very well as long as we stay in C# and work directly with the driver.

But it is very cumbersome working with the guids directly in the database i.e. through mongosh or mongodb compass. The GUIDs are in binary format v3.
image

In case we want to debug and directly lookup a GUID we couldn’t get it to work. We tried using the uuidhelper.js script which is in the mongodb c# driver repository but it does not seem to work with mongosh.

We get the following error this.base64 is not a function. when calling .toCSUUID().

When using the methods to convert any GUID from the application via CSUUID(xxxxx) the system does not return data. I assume there is something wrong with the script and the format doesn’t fit.

Is there any updated version of the script? Is there any way to use it with mongoDB compass.

Thanks in advance!

Hi, @d_r,

Welcome to the MongoDB Community Forums. I understand that you’re having some challenges using GUIDs for primary keys in your C# applications and how they are rendered by mongosh.

Regarding the uuidhelpers.js script, those helper functions were written for the previous mongo shell and have not been updated for the new mongosh shell. Apologies for the confusion. Follow CSHARP-4786 for more information.

The root cause of the problem is that legacy GUIDs (subtype 3) do not have a defined byte ordering. The byte ordering varies by language (C#, Python, and Java can use different byte ordering). We introduced GUID subtype 4 (aka GuidRepresentation.Standard), which does have a defined byte ordering. We couldn’t simply make this the default as it would be a backward breaking change.

If you are writing a net new application, I would strongly recommend using GuidRepresentationMode.V3 and GuidRepresentation.Standard (subtype 4) for all your GUIDs. Another option is to use ObjectId instead as it has similar properties to GUIDs without the hassles around byte ordering inconsistencies.

If you are working with existing data that contains subtype 3 GUIDs, you should configure your GuidRepresentation based on the application that generated the data so that your C# application interprets the byte order correctly. If you need to work with these GUIDs in mongosh, you can add the following functions to uuidhelpers.js so that the script works with {{mongosh}}.

BinData.prototype.base64 = function() { return this.buffer.base64Slice(); };
BinData.prototype.subtype = function() { return this.sub_type; };

You can read more about the GuidRepresentationMode and how to set it in GUID Serialization in the .NET/C# Driver documentation. For an in-depth discussion of the various legacy GUID byte ordering issues, I would recommend Handling UUID Data in the Python Driver documentation. (We are adding this information to the .NET/C# docs, but haven’t completed it yet.)

I hope this helps answer your questions.

Sincerely,
James

Hey @James_Kovacs ,

thank you very much for the detailed answer. We are working on a new project so we will switch to V3 GuidRepresentation and RepresentationMode V3.

I added the following in our Program.cs and it is working.

BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
#pragma warning disable CS0618 // Error in mongodb driver reference https://jira.mongodb.org/browse/CSHARP-3195
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
#pragma warning restore CS0618

Thanks!

Hi, @d_r,

Glad I could be of assistance. Thank you for using MongoDB!

Sincerely,
James

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.