parent
2d2400e7fa
commit
950b3873b1
|
|
@ -2,7 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Microsoft.JSInterop
|
namespace Microsoft.JSInterop
|
||||||
|
|
@ -11,13 +11,10 @@ namespace Microsoft.JSInterop
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type typeToConvert)
|
public override bool CanConvert(Type typeToConvert)
|
||||||
{
|
{
|
||||||
Debug.Assert(
|
return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(DotNetObjectRef<>);
|
||||||
typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(DotNetObjectRef<>),
|
|
||||||
"We expect this to only be called for DotNetObjectRef<T> instances.");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override JsonConverter CreateConverter(Type typeToConvert)
|
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions jsonSerializerOptions)
|
||||||
{
|
{
|
||||||
// System.Text.Json handles caching the converters per type on our behalf. No caching is required here.
|
// System.Text.Json handles caching the converters per type on our behalf. No caching is required here.
|
||||||
var instanceType = typeToConvert.GetGenericArguments()[0];
|
var instanceType = typeToConvert.GetGenericArguments()[0];
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
@ -14,27 +13,31 @@ namespace Microsoft.JSInterop
|
||||||
|
|
||||||
public override DotNetObjectRef<TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override DotNetObjectRef<TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
if (!reader.Read())
|
long dotNetObjectId = 0;
|
||||||
|
|
||||||
|
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("Invalid DotNetObjectRef JSON.");
|
if (reader.TokenType == JsonTokenType.PropertyName)
|
||||||
|
{
|
||||||
|
if (reader.ValueTextEquals(DotNetObjectRefKey.EncodedUtf8Bytes))
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
dotNetObjectId = reader.GetInt64();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException($"Unexcepted JSON property {reader.GetString()}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException($"Unexcepted JSON Token {reader.TokenType}.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reader.TokenType != JsonTokenType.PropertyName || !reader.ValueTextEquals(DotNetObjectRefKey.EncodedUtf8Bytes))
|
if (dotNetObjectId is 0)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("Invalid DotNetObjectRef JSON.");
|
throw new JsonException($"Required property {DotNetObjectRefKey} not found.");
|
||||||
}
|
|
||||||
|
|
||||||
if (!reader.Read())
|
|
||||||
{
|
|
||||||
throw new InvalidDataException("Invalid DotNetObjectRef JSON.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var dotNetObjectId = reader.GetInt64();
|
|
||||||
|
|
||||||
if (!reader.Read())
|
|
||||||
{
|
|
||||||
// We need to read all the data that was given to us.
|
|
||||||
throw new InvalidDataException("Invalid DotNetObjectRef JSON.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = (TValue)DotNetObjectRefManager.Current.FindDotNetObject(dotNetObjectId);
|
var value = (TValue)DotNetObjectRefManager.Current.FindDotNetObject(dotNetObjectId);
|
||||||
|
|
|
||||||
|
|
@ -30,23 +30,5 @@ namespace Microsoft.JSInterop
|
||||||
var ex = Assert.Throws<ArgumentException>(() => jsRuntime.ObjectRefManager.FindDotNetObject(objRef.ObjectId));
|
var ex = Assert.Throws<ArgumentException>(() => jsRuntime.ObjectRefManager.FindDotNetObject(objRef.ObjectId));
|
||||||
Assert.StartsWith("There is no tracked object with id '1'.", ex.Message);
|
Assert.StartsWith("There is no tracked object with id '1'.", ex.Message);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
protected internal override void EndInvokeDotNet(string callId, bool success, object resultOrError, string assemblyName, string methodIdentifier, long dotNetObjectId)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task WithJSRuntime(Action<JSRuntimeBase> testCode)
|
|
||||||
{
|
|
||||||
// Since the tests rely on the asynclocal JSRuntime.Current, ensure we
|
|
||||||
// are on a distinct async context with a non-null JSRuntime.Current
|
|
||||||
await Task.Yield();
|
|
||||||
|
|
||||||
var runtime = new TestJSRuntime();
|
|
||||||
JSRuntime.SetCurrentJSRuntime(runtime);
|
|
||||||
testCode(runtime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,58 @@ namespace Microsoft.JSInterop.Tests
|
||||||
{
|
{
|
||||||
public class DotNetObjectReferenceJsonConverterTest
|
public class DotNetObjectReferenceJsonConverterTest
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public Task Read_Throws_IfJsonIsMissingDotNetObjectProperty() => WithJSRuntime(_ =>
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dotNetObjectRef = DotNetObjectRef.Create(new TestModel());
|
||||||
|
|
||||||
|
var json = "{}";
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var ex = Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<DotNetObjectRef<TestModel>>(json));
|
||||||
|
Assert.Equal("Required property __dotNetObject not found.", ex.Message);
|
||||||
|
});
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public Task Read_Throws_IfJsonContainsUnknownContent() => WithJSRuntime(_ =>
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dotNetObjectRef = DotNetObjectRef.Create(new TestModel());
|
||||||
|
|
||||||
|
var json = "{\"foo\":2}";
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var ex = Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<DotNetObjectRef<TestModel>>(json));
|
||||||
|
Assert.Equal("Unexcepted JSON property foo.", ex.Message);
|
||||||
|
});
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public Task Read_ReadsJson() => WithJSRuntime(_ =>
|
public Task Read_ReadsJson() => WithJSRuntime(_ =>
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Throw-away value
|
var input = new TestModel();
|
||||||
|
var dotNetObjectRef = DotNetObjectRef.Create(input);
|
||||||
|
var objectId = dotNetObjectRef.ObjectId;
|
||||||
|
|
||||||
|
var json = $"{{\"__dotNetObject\":{objectId}}}";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var deserialized = JsonSerializer.Deserialize<DotNetObjectRef<TestModel>>(json);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Same(input, deserialized.Value);
|
||||||
|
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());
|
||||||
|
DotNetObjectRef.Create(new TestModel());
|
||||||
|
|
||||||
var input = new TestModel();
|
var input = new TestModel();
|
||||||
var dotNetObjectRef = DotNetObjectRef.Create(input);
|
var dotNetObjectRef = DotNetObjectRef.Create(input);
|
||||||
var objectId = dotNetObjectRef.ObjectId;
|
var objectId = dotNetObjectRef.ObjectId;
|
||||||
|
|
@ -34,8 +80,6 @@ namespace Microsoft.JSInterop.Tests
|
||||||
public Task Read_ReadsJson_WithFormatting() => WithJSRuntime(_ =>
|
public Task Read_ReadsJson_WithFormatting() => WithJSRuntime(_ =>
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Throw-away value
|
|
||||||
DotNetObjectRef.Create(new TestModel());
|
|
||||||
var input = new TestModel();
|
var input = new TestModel();
|
||||||
var dotNetObjectRef = DotNetObjectRef.Create(input);
|
var dotNetObjectRef = DotNetObjectRef.Create(input);
|
||||||
var objectId = dotNetObjectRef.ObjectId;
|
var objectId = dotNetObjectRef.ObjectId;
|
||||||
|
|
@ -57,8 +101,6 @@ namespace Microsoft.JSInterop.Tests
|
||||||
public Task WriteJsonTwice_KeepsObjectId() => WithJSRuntime(_ =>
|
public Task WriteJsonTwice_KeepsObjectId() => WithJSRuntime(_ =>
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Throw-away value
|
|
||||||
DotNetObjectRef.Create(new TestModel());
|
|
||||||
var dotNetObjectRef = DotNetObjectRef.Create(new TestModel());
|
var dotNetObjectRef = DotNetObjectRef.Create(new TestModel());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,11 @@ namespace Microsoft.JSInterop
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected internal override void EndInvokeDotNet(string callId, bool success, object resultOrError, string assemblyName, string methodIdentifier, long dotNetObjectId)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task WithJSRuntime(Action<JSRuntimeBase> testCode)
|
public static async Task WithJSRuntime(Action<JSRuntimeBase> testCode)
|
||||||
{
|
{
|
||||||
// Since the tests rely on the asynclocal JSRuntime.Current, ensure we
|
// Since the tests rely on the asynclocal JSRuntime.Current, ensure we
|
||||||
Loading…
Reference in New Issue