Skip to content

Commit 8ba324e

Browse files
author
rstam
committed
CSHARP-961: Add error message when deserializing a nominal type that is an interface and there is no discriminator to determine the actual type.
1 parent 10cfbad commit 8ba324e

File tree

3 files changed

+133
-6
lines changed

3 files changed

+133
-6
lines changed

MongoDB.Bson/Serialization/Serializers/InterfaceSerializer.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,6 @@ public override object Deserialize(
7070

7171
var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType);
7272
var actualType = discriminatorConvention.GetActualType(bsonReader, nominalType);
73-
if (actualType == nominalType)
74-
{
75-
var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is the interface {0}.", nominalType);
76-
throw new FileFormatException(message);
77-
}
78-
7973
return Deserialize(bsonReader, nominalType, actualType, options);
8074
}
8175

@@ -93,6 +87,18 @@ public override object Deserialize(
9387
Type actualType,
9488
IBsonSerializationOptions options)
9589
{
90+
if (!nominalType.IsInterface)
91+
{
92+
var message = string.Format("Nominal type must be an interface, not {0}.", nominalType.FullName);
93+
throw new ArgumentException(message, "nominalType");
94+
}
95+
96+
if (actualType == nominalType)
97+
{
98+
var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is the interface {0}.", nominalType);
99+
throw new FileFormatException(message);
100+
}
101+
96102
var serializer = BsonSerializer.LookupSerializer(actualType);
97103
return serializer.Deserialize(bsonReader, nominalType, actualType, options);
98104
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/* Copyright 2010-2014 MongoDB 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.Collections.Generic;
17+
using System.IO;
18+
using MongoDB.Bson;
19+
using MongoDB.Bson.Serialization;
20+
using MongoDB.Bson.Serialization.Attributes;
21+
using MongoDB.Bson.Serialization.Conventions;
22+
using NUnit.Framework;
23+
24+
namespace MongoDB.BsonUnitTests.Jira
25+
{
26+
[TestFixture]
27+
public class CSharp961Tests
28+
{
29+
static CSharp961Tests()
30+
{
31+
BsonClassMap.RegisterClassMap<Parent>();
32+
BsonClassMap.RegisterClassMap<Child>();
33+
}
34+
35+
public interface IParent
36+
{
37+
[BsonId]
38+
BsonObjectId Id { get; set; }
39+
40+
[BsonElement("name")]
41+
string Name { get; set; }
42+
43+
[BsonElement("children")]
44+
Dictionary<string, IChild> StringToChildren { get; set; }
45+
}
46+
47+
public interface IChild
48+
{
49+
[BsonElement("name")]
50+
string Name { get; set; }
51+
}
52+
53+
public class Parent : IParent
54+
{
55+
[BsonId]
56+
public BsonObjectId Id { get; set; }
57+
58+
[BsonElement("name")]
59+
public string Name { get; set; }
60+
61+
[BsonElement("children")]
62+
public Dictionary<string, IChild> StringToChildren { get; set; }
63+
}
64+
65+
public class Child : IChild
66+
{
67+
[BsonElement("name")]
68+
public string Name { get; set; }
69+
}
70+
71+
private Parent _sampleParent = new Parent
72+
{
73+
Id = new ObjectId("535a524abfcae300b04cea7b"),
74+
Name = "ParentName",
75+
StringToChildren = new Dictionary<string, IChild>
76+
{
77+
{ "one", new Child { Name = "bob" } },
78+
{ "two", new Child { Name = "jane" } }
79+
}
80+
};
81+
82+
[Test]
83+
public void TestDeserializeWithDiscriminator()
84+
{
85+
var json = "{ '_id' : ObjectId('535a524abfcae300b04cea7b'), 'name' : 'ParentName', 'children' : { 'one' : { '_t' : 'Child', 'name' : 'bob' }, 'two' : { '_t' : 'Child', 'name' : 'jane' } } }";
86+
var deserializedParent = BsonSerializer.Deserialize<Parent>(json);
87+
Assert.IsTrue(ParentEquals(deserializedParent, _sampleParent));
88+
}
89+
90+
[Test]
91+
public void TestDeserializeWithoutDiscriminator()
92+
{
93+
var json = "{ '_id' : ObjectId('535a524abfcae300b04cea7b'), 'name' : 'ParentName', 'children' : { 'one' : { 'name' : 'bob' }, 'two' : { 'name' : 'jane' } } }";
94+
Assert.Throws<FileFormatException>(() => { var deserializedParent = BsonSerializer.Deserialize<Parent>(json); });
95+
}
96+
97+
[Test]
98+
public void TestSerialize()
99+
{
100+
var json = _sampleParent.ToJson();
101+
var expected = "{ '_id' : ObjectId('535a524abfcae300b04cea7b'), 'name' : 'ParentName', 'children' : { 'one' : { '_t' : 'Child', 'name' : 'bob' }, 'two' : { '_t' : 'Child', 'name' : 'jane' } } }";
102+
Assert.AreEqual(expected.Replace("'", "\""), json);
103+
}
104+
105+
private static bool ParentEquals(Parent lhs, Parent rhs)
106+
{
107+
if (lhs.Id != rhs.Id) { return false; }
108+
if (lhs.Name != rhs.Name) { return false; }
109+
if (lhs.StringToChildren.Count != rhs.StringToChildren.Count) { return false; }
110+
foreach (var pair in lhs.StringToChildren)
111+
{
112+
var lhsChild = pair.Value;
113+
IChild rhsChild;
114+
if (!rhs.StringToChildren.TryGetValue(pair.Key, out rhsChild)) { return false; }
115+
if (lhsChild.Name != rhsChild.Name) { return false; }
116+
}
117+
return true;
118+
}
119+
}
120+
}

MongoDB.BsonUnitTests/MongoDB.BsonUnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
<Compile Include="Jira\CSharp637Tests.cs" />
9292
<Compile Include="Jira\CSharp648Tests.cs" />
9393
<Compile Include="Jira\CSharp803Tests.cs" />
94+
<Compile Include="Jira\CSharp961Tests.cs" />
9495
<Compile Include="ObjectModel\LazyBsonArrayTests.cs" />
9596
<Compile Include="ObjectModel\LazyBsonDocumentTests.cs" />
9697
<Compile Include="ObjectModel\RawBsonArrayTests.cs" />

0 commit comments

Comments
 (0)