Skip to content

Commit

Permalink
Merge pull request #681 from eventflow/null-single-value-objects
Browse files Browse the repository at this point in the history
Fix: Deserializing "null" into nullable SingleValueObjects
  • Loading branch information
rasmus authored Sep 12, 2019
2 parents ff3be92 + bf03083 commit e65346b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
4 changes: 3 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### New in 0.75 (not released yet)

* _Nothing yet_
* Fix: When deserializing the JSON value `"null"` into a struct value like
`int`, the `SingleValueObjectConverter` threw an exception instead of
merely returning `null` representing an absent `SingleValueObject<int>` value

### New in 0.74.3948 (released 2019-07-01)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ public void EqualsForDifferentValues()

private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
};

[JsonConverter(typeof(SingleValueObjectConverter))]
Expand Down Expand Up @@ -202,6 +203,20 @@ public void DeserializeNullableIntWithoutValue()
with.I.Should().BeNull();
}

[Test]
public void DeserializeNullableIntWithNullValue()
{
// Arrange
var json = "{\"i\":null}";

// Act
var with = JsonConvert.DeserializeObject<WithNullableIntSingleValue>(json);

// Assert
with.Should().NotBeNull();
with.I.Should().BeNull();
}

[Test]
public void DeserializeNullableIntWithValue()
{
Expand Down
16 changes: 11 additions & 5 deletions Source/EventFlow/ValueObjects/SingleValueObjectConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,26 @@ namespace EventFlow.ValueObjects
{
public class SingleValueObjectConverter : JsonConverter
{
private static readonly ConcurrentDictionary<Type, Type> ConstructorArgumenTypes = new ConcurrentDictionary<Type, Type>();
private static readonly ConcurrentDictionary<Type, Type> ConstructorArgumentTypes = new ConcurrentDictionary<Type, Type>();

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var singleValueObject = value as ISingleValueObject;
if (singleValueObject == null)
if (!(value is ISingleValueObject singleValueObject))
{
return;
}

serializer.Serialize(writer, singleValueObject.GetValue());
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var parameterType = ConstructorArgumenTypes.GetOrAdd(
if (reader.Value == null)
{
return null;
}

var parameterType = ConstructorArgumentTypes.GetOrAdd(
objectType,
t =>
{
Expand All @@ -55,7 +60,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
});

var value = serializer.Deserialize(reader, parameterType);
return Activator.CreateInstance(objectType, new[] { value });

return Activator.CreateInstance(objectType, value);
}

public override bool CanConvert(Type objectType)
Expand Down

0 comments on commit e65346b

Please sign in to comment.