Skip to content

Commit

Permalink
SimpleJson fails with DateTime used as Dictionary key (#5141)
Browse files Browse the repository at this point in the history
* Add failing test

* add some additional tests

* reuse existing serialization logic

* handle datetime dictionary keys
  • Loading branch information
bording authored Aug 20, 2018
1 parent 053e523 commit 85eda59
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
82 changes: 82 additions & 0 deletions src/NServiceBus.Core.Tests/Serializers/SimpleJsonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,83 @@ public void TestStringObjectDictionary()
Assert.AreEqual(input["obj2"].String, result["obj2"].String);
}

[Test]
public void TestDateTimeDictionaryKeys()
{
var date1 = new DateTime(2018, 1, 1);
var date2 = new DateTime(2017, 1, 1);

var input = new Dictionary<DateTime, int>
{
{date1, 1},
{date2, 2}
};
var json = SimpleJson.SerializeObject(input);
var result = SimpleJson.DeserializeObject<Dictionary<DateTime, int>>(json);

Assert.AreEqual(2, result.Count);
Assert.AreEqual(1, result[date1]);
Assert.AreEqual(2, result[date2]);
}

[Test]
public void TestDateTimeOffsetDictionaryKeys()
{
var date1 = new DateTimeOffset(new DateTime(2018, 1, 1), TimeSpan.FromHours(4));
var date2 = new DateTimeOffset(new DateTime(2017, 1, 1), TimeSpan.FromHours(-2));

var input = new Dictionary<DateTimeOffset, int>
{
{date1, 1},
{date2, 2}
};
var json = SimpleJson.SerializeObject(input);
var result = SimpleJson.DeserializeObject<Dictionary<DateTimeOffset, int>>(json);

Assert.AreEqual(2, result.Count);
Assert.AreEqual(1, result[date1]);
Assert.AreEqual(2, result[date2]);
}

[Test]
public void TestGuidDictionaryKeys()
{
var guid1 = Guid.NewGuid();
var guid2 = Guid.NewGuid();

var input = new Dictionary<Guid, int>
{
{guid1, 1},
{guid2, 2}
};
var json = SimpleJson.SerializeObject(input);
var result = SimpleJson.DeserializeObject<Dictionary<Guid, int>>(json);

Assert.AreEqual(2, result.Count);
Assert.AreEqual(1, result[guid1]);
Assert.AreEqual(2, result[guid2]);
}

[Test]
[Ignore("not supported")]
public void TestEnumDictionaryKeys()
{
var enum1 = SampleEnum.EnumValue2;
var enum2 = SampleEnum.EnumValue3;

var input = new Dictionary<SampleEnum, int>
{
{enum1, 1},
{enum2, 2}
};
var json = SimpleJson.SerializeObject(input);
var result = SimpleJson.DeserializeObject<Dictionary<SampleEnum, int>>(json);

Assert.AreEqual(2, result.Count);
Assert.AreEqual(1, result[enum1]);
Assert.AreEqual(2, result[enum2]);
}

[Test]
public void TestPocoClass()
{
Expand Down Expand Up @@ -250,4 +327,9 @@ class SamplePoco
class CustomDictionary : Dictionary<int, int>
{
}

enum SampleEnum
{
EnumValue1, EnumValue2, EnumValue3
}
}
19 changes: 18 additions & 1 deletion src/NServiceBus.Core/Serializers/SimpleJson/SimpleJson.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,24 @@ static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnu
if (stringKey != null)
SerializeString(stringKey, builder);
else
SerializeString(key.ToString(), builder);
{
// alternative approach:
// jsonSerializerStrategy.TrySerializeNonPrimitiveObject(key, out var keyValue);
// SerializeString((keyValue as string) ?? key.ToString(), builder);

switch (key)
{
case DateTime d:
SerializeString(d.ToString("O", CultureInfo.InvariantCulture), builder);
break;
case DateTimeOffset d:
SerializeString(d.ToString("O", CultureInfo.InvariantCulture), builder);
break;
default:
SerializeString(key.ToString(), builder);
break;
}
}
builder.Append(":");
if (!SerializeValue(jsonSerializerStrategy, value, builder))
return false;
Expand Down

0 comments on commit 85eda59

Please sign in to comment.