Skip to content

Commit 98a0129

Browse files
author
rstam
committed
CSHARP-564: fix serialization of properties declared as an interface and having a value of null.
1 parent aa6fc73 commit 98a0129

File tree

3 files changed

+94
-12
lines changed

3 files changed

+94
-12
lines changed

Bson/Serialization/BsonClassMapSerializer.cs

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -473,19 +473,30 @@ private void DeserializeMember(BsonReader bsonReader, object obj, BsonMemberMap
473473
{
474474
try
475475
{
476+
object value;
477+
476478
var nominalType = memberMap.MemberType;
477-
Type actualType;
478-
if (bsonReader.GetCurrentBsonType() == BsonType.Null)
479+
var bsonType = bsonReader.GetCurrentBsonType();
480+
if (bsonType == BsonType.Null && nominalType.IsInterface)
479481
{
480-
actualType = nominalType;
482+
bsonReader.ReadNull();
483+
value = null;
481484
}
482-
else
483-
{
484-
var discriminatorConvention = memberMap.GetDiscriminatorConvention();
485-
actualType = discriminatorConvention.GetActualType(bsonReader, nominalType); // returns nominalType if no discriminator found
485+
else{
486+
Type actualType;
487+
if (bsonType == BsonType.Null)
488+
{
489+
actualType = nominalType;
490+
}
491+
else
492+
{
493+
var discriminatorConvention = memberMap.GetDiscriminatorConvention();
494+
actualType = discriminatorConvention.GetActualType(bsonReader, nominalType); // returns nominalType if no discriminator found
495+
}
496+
var serializer = memberMap.GetSerializer(actualType);
497+
value = serializer.Deserialize(bsonReader, nominalType, actualType, memberMap.SerializationOptions);
486498
}
487-
var serializer = memberMap.GetSerializer(actualType);
488-
var value = serializer.Deserialize(bsonReader, nominalType, actualType, memberMap.SerializationOptions);
499+
489500
memberMap.Setter(obj, value);
490501
}
491502
catch (Exception ex)
@@ -541,10 +552,18 @@ private void SerializeMember(BsonWriter bsonWriter, object obj, BsonMemberMap me
541552
}
542553

543554
bsonWriter.WriteName(memberMap.ElementName);
555+
544556
var nominalType = memberMap.MemberType;
545-
var actualType = (value == null) ? nominalType : value.GetType();
546-
var serializer = memberMap.GetSerializer(actualType);
547-
serializer.Serialize(bsonWriter, nominalType, value, memberMap.SerializationOptions);
557+
if (value == null && nominalType.IsInterface)
558+
{
559+
bsonWriter.WriteNull();
560+
}
561+
else
562+
{
563+
var actualType = (value == null) ? nominalType : value.GetType();
564+
var serializer = memberMap.GetSerializer(actualType);
565+
serializer.Serialize(bsonWriter, nominalType, value, memberMap.SerializationOptions);
566+
}
548567
}
549568

550569
private void VerifyNominalType(Type nominalType)

BsonUnitTests/BsonUnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
<Compile Include="Jira\CSharp467Tests.cs" />
152152
<Compile Include="Jira\CSharp479Tests.cs" />
153153
<Compile Include="Jira\CSharp515Tests.cs" />
154+
<Compile Include="Jira\CSharp564Tests.cs" />
154155
<Compile Include="Jira\CSharp70Tests.cs" />
155156
<Compile Include="Jira\CSharp71Tests.cs" />
156157
<Compile Include="Jira\CSharp74Tests.cs" />

BsonUnitTests/Jira/CSharp564Tests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* Copyright 2010-2012 10gen Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using System.Text;
20+
using NUnit.Framework;
21+
22+
using MongoDB.Bson;
23+
using MongoDB.Bson.Serialization;
24+
25+
namespace MongoDB.BsonUnitTests.Jira.CSharp564
26+
{
27+
[TestFixture]
28+
public class CSharp564Tests
29+
{
30+
interface IWhatever { }
31+
class Whatever : IWhatever { }
32+
33+
class Person
34+
{
35+
public IWhatever Whatever { get; set; }
36+
}
37+
38+
[Test]
39+
public void TestPersonWhateverNull()
40+
{
41+
var p = new Person();
42+
var json = p.ToJson();
43+
var expected = "{ 'Whatever' : null }".Replace("'", "\"");
44+
Assert.AreEqual(expected, json);
45+
46+
var r = BsonSerializer.Deserialize<Person>(json);
47+
Assert.AreEqual(null, r.Whatever);
48+
}
49+
50+
[Test]
51+
public void TestPersonWhateverNotNull()
52+
{
53+
var p = new Person() { Whatever = new Whatever() };
54+
var json = p.ToJson();
55+
var expected = "{ 'Whatever' : { '_t' : 'Whatever' } }".Replace("'", "\"");
56+
Assert.AreEqual(expected, json);
57+
58+
var r = BsonSerializer.Deserialize<Person>(json);
59+
Assert.IsInstanceOf<Whatever>(r.Whatever);
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)