diff --git a/src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReferenceJsonConverter.cs b/src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReferenceJsonConverter.cs index 487b4c77b0..eaabdbf9e6 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReferenceJsonConverter.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/DotNetObjectReferenceJsonConverter.cs @@ -19,7 +19,7 @@ namespace Microsoft.JSInterop { if (reader.TokenType == JsonTokenType.PropertyName) { - if (reader.ValueTextEquals(DotNetObjectRefKey.EncodedUtf8Bytes)) + if (dotNetObjectId == 0 && reader.ValueTextEquals(DotNetObjectRefKey.EncodedUtf8Bytes)) { reader.Read(); dotNetObjectId = reader.GetInt64(); diff --git a/src/JSInterop/Microsoft.JSInterop/test/DotNetObjectReferenceJsonConverterTest.cs b/src/JSInterop/Microsoft.JSInterop/test/DotNetObjectReferenceJsonConverterTest.cs index be1d2bf975..18f3db55c1 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/DotNetObjectReferenceJsonConverterTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/DotNetObjectReferenceJsonConverterTest.cs @@ -36,6 +36,36 @@ namespace Microsoft.JSInterop.Tests Assert.Equal("Unexcepted JSON property foo.", ex.Message); }); + [Fact] + public Task Read_Throws_IfJsonIsIncomplete() => WithJSRuntime(_ => + { + // Arrange + var input = new TestModel(); + var dotNetObjectRef = DotNetObjectRef.Create(input); + var objectId = dotNetObjectRef.ObjectId; + + var json = $"{{\"__dotNetObject\":{objectId}"; + + // Act & Assert + var ex = Record.Exception(() => JsonSerializer.Deserialize>(json)); + Assert.IsAssignableFrom(ex); + }); + + [Fact] + public Task Read_Throws_IfDotNetObjectIdAppearsMultipleTimes() => WithJSRuntime(_ => + { + // Arrange + var input = new TestModel(); + var dotNetObjectRef = DotNetObjectRef.Create(input); + var objectId = dotNetObjectRef.ObjectId; + + var json = $"{{\"__dotNetObject\":{objectId},\"__dotNetObject\":{objectId}}}"; + + // Act & Assert + var ex = Record.Exception(() => JsonSerializer.Deserialize>(json)); + Assert.IsAssignableFrom(ex); + }); + [Fact] public Task Read_ReadsJson() => WithJSRuntime(_ => { @@ -54,26 +84,25 @@ namespace Microsoft.JSInterop.Tests Assert.Equal(objectId, deserialized.ObjectId); }); + [Fact] public Task Read_ReturnsTheCorrectInstance() => WithJSRuntime(_ => { // Arrange - // Track a few instances and verify that the deserialized value returns the corect value. - DotNetObjectRef.Create(new TestModel()); - DotNetObjectRef.Create(new TestModel()); + // Track a few instances and verify that the deserialized value returns the correct value. + var instance1 = new TestModel(); + var instance2 = new TestModel(); + var ref1 = DotNetObjectRef.Create(instance1); + var ref2 = DotNetObjectRef.Create(instance2); - var input = new TestModel(); - var dotNetObjectRef = DotNetObjectRef.Create(input); - var objectId = dotNetObjectRef.ObjectId; - - var json = $"{{\"__dotNetObject\":{objectId}}}"; + var json = $"[{{\"__dotNetObject\":{ref2.ObjectId}}},{{\"__dotNetObject\":{ref1.ObjectId}}}]"; // Act - var deserialized = JsonSerializer.Deserialize>(json); + var deserialized = JsonSerializer.Deserialize[]>(json); // Assert - Assert.Same(input, deserialized.Value); - Assert.Equal(objectId, deserialized.ObjectId); + Assert.Same(instance2, deserialized[0].Value); + Assert.Same(instance1, deserialized[1].Value); }); [Fact]