Skip to content

Commit

Permalink
Fixed CSHARP-121. Added support for serializing Guids as strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
rstam committed Dec 3, 2010
1 parent 4d03097 commit e3157e2
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 15 deletions.
61 changes: 46 additions & 15 deletions Bson/DefaultSerializer/Serializers/BsonPrimitiveSerializers.cs
Expand Up @@ -359,23 +359,37 @@ bool serializeIdFirst

public class GuidSerializer : BsonBaseSerializer {
#region private static fields
private static GuidSerializer singleton = new GuidSerializer();
private static GuidSerializer binaryRepresentation = new GuidSerializer(BsonType.Binary);
private static GuidSerializer stringRepresentation = new GuidSerializer(BsonType.String);
#endregion

#region private fields
private BsonType representation;
#endregion

#region constructors
private GuidSerializer() {
private GuidSerializer(
BsonType representation
) {
this.representation = representation;
}
#endregion

#region public static properties
public static GuidSerializer Singleton {
get { return singleton; }
public static GuidSerializer BinaryRepresentation {
get { return binaryRepresentation; }
}

public static GuidSerializer StringRepresentation {
get { return stringRepresentation; }
}
#endregion

#region public static methods
public static void RegisterSerializers() {
BsonSerializer.RegisterSerializer(typeof(Guid), singleton);
BsonSerializer.RegisterSerializer(typeof(Guid), null, binaryRepresentation); // default representation
BsonSerializer.RegisterSerializer(typeof(Guid), BsonType.Binary, binaryRepresentation);
BsonSerializer.RegisterSerializer(typeof(Guid), BsonType.String, stringRepresentation);
}
#endregion

Expand All @@ -384,16 +398,24 @@ public class GuidSerializer : BsonBaseSerializer {
BsonReader bsonReader,
Type nominalType
) {
byte[] bytes;
BsonBinarySubType subType;
bsonReader.ReadBinaryData(out bytes, out subType);
if (bytes.Length != 16) {
throw new FileFormatException("BinaryData length is not 16");
}
if (subType != BsonBinarySubType.Uuid) {
throw new FileFormatException("BinaryData sub type is not Uuid");
BsonType bsonType = bsonReader.CurrentBsonType;
if (bsonType == BsonType.Binary) {
byte[] bytes;
BsonBinarySubType subType;
bsonReader.ReadBinaryData(out bytes, out subType);
if (bytes.Length != 16) {
throw new FileFormatException("BinaryData length is not 16");
}
if (subType != BsonBinarySubType.Uuid) {
throw new FileFormatException("BinaryData sub type is not Uuid");
}
return new Guid(bytes);
} else if (bsonType == BsonType.String) {
return new Guid(bsonReader.ReadString());
} else {
var message = string.Format("Cannot deserialize Guid from BsonType: {0}", bsonType);
throw new FileFormatException(message);
}
return new Guid(bytes);
}

public override void Serialize(
Expand All @@ -403,7 +425,16 @@ Type nominalType
bool serializeIdFirst
) {
var guid = (Guid) value;
bsonWriter.WriteBinaryData(guid.ToByteArray(), BsonBinarySubType.Uuid);
switch (representation) {
case BsonType.Binary:
bsonWriter.WriteBinaryData(guid.ToByteArray(), BsonBinarySubType.Uuid);
break;
case BsonType.String:
bsonWriter.WriteString(guid.ToString());
break;
default:
throw new BsonInternalException("Unexpected representation");
}
}
#endregion
}
Expand Down
1 change: 1 addition & 0 deletions BsonUnitTests/BsonUnitTests.csproj
Expand Up @@ -101,6 +101,7 @@
<Compile Include="Jira\CSharp102Tests.cs" />
<Compile Include="Jira\CSharp104Tests.cs" />
<Compile Include="Jira\CSharp116Tests.cs" />
<Compile Include="Jira\CSharp121Tests.cs" />
<Compile Include="Jira\CSharp70Tests.cs" />
<Compile Include="Jira\CSharp71Tests.cs" />
<Compile Include="Jira\CSharp74Tests.cs" />
Expand Down
51 changes: 51 additions & 0 deletions BsonUnitTests/Jira/CSharp121Tests.cs
@@ -0,0 +1,51 @@
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using NUnit.Framework;

using MongoDB.Bson;
using MongoDB.Bson.DefaultSerializer;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;

namespace MongoDB.BsonUnitTests.Jira.CSharp121 {
public class C {
[BsonRepresentation(BsonType.String)]
public Guid PhotoId { get; set; }
}

[TestFixture]
public class CSharp121Tests {
[Test]
public void TestGuidStringRepresentation() {
var c = new C { PhotoId = Guid.Empty };
var json = c.ToJson();
var expected = "{ 'PhotoId' : '00000000-0000-0000-0000-000000000000' }".Replace("'", "\"");
Assert.AreEqual(expected, json);

var bson = c.ToBson();
var rehydrated = BsonSerializer.Deserialize<C>(bson);
Assert.IsInstanceOf<C>(rehydrated);
Assert.AreEqual(c.PhotoId, rehydrated.PhotoId);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
}
}

0 comments on commit e3157e2

Please sign in to comment.