React to more changes

This commit is contained in:
Pranav K 2019-08-16 07:16:14 -07:00
parent 4493d0784f
commit 203caa020f
No known key found for this signature in database
GPG Key ID: 1963DA6D96C3057A
22 changed files with 145 additions and 95 deletions

View File

@ -38,7 +38,6 @@ namespace Microsoft.AspNetCore.Blazor.Hosting
// this happens in the browser it will be a direct call from Mono. We effectively needs to set the
// JSRuntime in the 'root' execution context which implies that we want to do as part of a direct
// call from Program.Main, and before any 'awaits'.
JSRuntime.SetCurrentJSRuntime(_runtime);
SetBrowserHttpMessageHandlerAsDefault();
return StartAsyncAwaited();

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
@ -13,9 +13,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\Shared\src\BrowserNavigationManagerInterop.cs" />
<Compile Include="..\..\..\Shared\src\JsonSerializerOptionsProvider.cs" />
<Compile Include="..\..\..\Shared\src\WebEventData.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\BrowserNavigationManagerInterop.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerializerOptionsProvider.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\WebEventData.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\ElementReferenceJsonConverter.cs" />
</ItemGroup>
</Project>

View File

@ -1,12 +1,34 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Components;
using Mono.WebAssembly.Interop;
namespace Microsoft.AspNetCore.Blazor.Services
{
internal static class WebAssemblyJSRuntime
internal sealed class WebAssemblyJSRuntime : MonoWebAssemblyJSRuntime
{
public static readonly MonoWebAssemblyJSRuntime Instance = new MonoWebAssemblyJSRuntime();
private static readonly WebAssemblyJSRuntime _instance = new WebAssemblyJSRuntime();
private static bool _initialized;
public WebAssemblyJSRuntime()
{
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter());
}
public static WebAssemblyJSRuntime Instance
{
get
{
if (!_initialized)
{
// This is executing in MonoWASM. Consequently we do not to have concern ourselves with thread safety.
_initialized = true;
Initialize(_instance);
}
return _instance;
}
}
}
}

View File

@ -120,7 +120,7 @@ namespace Test
AdditionalSyntaxTrees.Add(GenericContextComponent);
var component = CompileToComponent(@"
<GenericContext TItem=int Items=""@(new List<int>() { 1, 2, })"" @ref=""_my"" @ref:suppressField />
<GenericContext TItem=int Items=""@(new List<int>() { 1, 2, })"" @ref=""_my"" />
@code {
GenericContext<int> _my;
@ -187,7 +187,7 @@ namespace Test
AdditionalSyntaxTrees.Add(GenericContextComponent);
var component = CompileToComponent(@"
<GenericContext Items=""@(new List<int>() { 1, 2, })"" @ref=""_my"" @ref:suppressField />
<GenericContext Items=""@(new List<int>() { 1, 2, })"" @ref=""_my"" />
@code {
GenericContext<int> _my;
@ -220,7 +220,7 @@ namespace Test
var assembly = CompileToAssembly("Test.cshtml", @"
@typeparam TItem
<GenericContext Items=""@MyItems"" @ref=""_my"" @ref:suppressField />
<GenericContext Items=""@MyItems"" @ref=""_my"" />
@code {
[Parameter] public List<TItem> MyItems { get; set; }

View File

@ -5,13 +5,12 @@
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<Compile Include="Microsoft.AspNetCore.Components.netstandard2.0.cs" />
<Reference Include="Microsoft.JSInterop" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<Reference Include="System.Buffers" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<Compile Include="Microsoft.AspNetCore.Components.netcoreapp3.0.cs" />
<Reference Include="Microsoft.JSInterop" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>

View File

@ -110,6 +110,8 @@ namespace Microsoft.AspNetCore.Components
public readonly partial struct ElementReference
{
private readonly object _dummy;
public ElementReference(string id) { throw null; }
public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct EventCallback

View File

@ -110,6 +110,8 @@ namespace Microsoft.AspNetCore.Components
public readonly partial struct ElementReference
{
private readonly object _dummy;
public ElementReference(string id) { throw null; }
public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct EventCallback

View File

@ -3,8 +3,6 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
namespace Microsoft.AspNetCore.Components
@ -12,7 +10,6 @@ namespace Microsoft.AspNetCore.Components
/// <summary>
/// Represents a reference to a rendered element.
/// </summary>
[JsonConverter(typeof(ElementReferenceConverter))]
public readonly struct ElementReference
{
private static long _nextIdForWebAssemblyOnly = 1;
@ -24,9 +21,9 @@ namespace Microsoft.AspNetCore.Components
/// The Id is unique at least within the scope of a given user/circuit.
/// This property is public to support Json serialization and should not be used by user code.
/// </remarks>
internal string Id { get; }
public string Id { get; }
private ElementReference(string id)
public ElementReference(string id)
{
Id = id;
}
@ -54,48 +51,5 @@ namespace Microsoft.AspNetCore.Components
return Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture);
}
}
private sealed class ElementReferenceConverter : JsonConverter<ElementReference>
{
private static readonly JsonEncodedText IdProperty = JsonEncodedText.Encode("__internalId");
public override ElementReference Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string id = null;
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(IdProperty.EncodedUtf8Bytes))
{
reader.Read();
id = reader.GetString();
}
else
{
throw new JsonException($"Unexpected JSON property '{reader.GetString()}'.");
}
}
else
{
throw new JsonException($"Unexcepted JSON Token {reader.TokenType}.");
}
}
if (id is null)
{
throw new JsonException("__internalId is required.");
}
return new ElementReference(id);
}
public override void Write(Utf8JsonWriter writer, ElementReference value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(IdProperty, value.Id);
writer.WriteEndObject();
}
}
}
}

View File

@ -10,16 +10,18 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\Shared\src\JsonSerializerOptionsProvider.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.JSInterop" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<Reference Include="System.Buffers" />
</ItemGroup>
<Target Name="_GetNuspecDependencyPackageVersions">
<MSBuild Targets="_GetPackageVersionInfo"
BuildInParallel="$(BuildInParallel)"

View File

@ -12,7 +12,6 @@ using Microsoft.AspNetCore.Components.Web.Rendering;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.JSInterop;
using Microsoft.JSInterop.Infrastructure;
namespace Microsoft.AspNetCore.Components.Server.Circuits
@ -26,11 +25,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
private bool _initialized;
private bool _disposed;
/// <summary>
/// Sets the <see cref="IJSRuntime"/> for the current excution context.
/// </summary>
public void SetCurrentJSRuntime() => JSInterop.JSRuntime.SetCurrentJSRuntime(JSRuntime);
// This event is fired when there's an unrecoverable exception coming from the circuit, and
// it need so be torn down. The registry listens to this even so that the circuit can
// be torn down even when a client is not connected.
@ -101,7 +95,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
try
{
SetCurrentJSRuntime();
_initialized = true; // We're ready to accept incoming JSInterop calls from here on
await OnCircuitOpenedAsync(cancellationToken);
@ -341,9 +334,8 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
{
await Renderer.Dispatcher.InvokeAsync(() =>
{
SetCurrentJSRuntime();
Log.BeginInvokeDotNet(_logger, callId, assemblyName, methodIdentifier, dotNetObjectId);
DotNetDispatcher.BeginInvokeDotNet(callId, assemblyName, methodIdentifier, dotNetObjectId, argsJson);
DotNetDispatcher.BeginInvokeDotNet(JSRuntime, callId, assemblyName, methodIdentifier, dotNetObjectId, argsJson);
});
}
catch (Exception ex)
@ -367,7 +359,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
{
await Renderer.Dispatcher.InvokeAsync(() =>
{
SetCurrentJSRuntime();
if (!succeded)
{
// We can log the arguments here because it is simply the JS error with the call stack.
@ -378,7 +369,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
Log.EndInvokeJSSucceeded(_logger, asyncCall);
}
DotNetDispatcher.EndInvokeJS(arguments);
DotNetDispatcher.EndInvokeJS(JSRuntime, arguments);
});
}
catch (Exception ex)
@ -416,7 +407,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
{
await Renderer.Dispatcher.InvokeAsync(() =>
{
SetCurrentJSRuntime();
return Renderer.DispatchEventAsync(
webEventData.EventHandlerId,
webEventData.EventFieldInfo,
@ -444,7 +434,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
{
await Renderer.Dispatcher.InvokeAsync(() =>
{
SetCurrentJSRuntime();
Log.LocationChange(_logger, uri, CircuitId);
var navigationManager = (RemoteNavigationManager)Services.GetRequiredService<NavigationManager>();
navigationManager.NotifyLocationChanged(uri, intercepted);

View File

@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
_options = options.Value;
_logger = logger;
DefaultAsyncTimeout = _options.JSInteropDefaultCallTimeout;
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter());
}
internal void Initialize(CircuitClientProxy clientProxy)
@ -58,7 +59,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
{
_clientProxy.SendAsync(
"JS.EndInvokeDotNet",
JsonSerializer.Serialize(new[] { callId, success, resultOrError }, JsonSerializerOptionsProvider.Options));
JsonSerializer.Serialize(new[] { callId, success, resultOrError }, JsonSerializerOptions));
}
protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson)

View File

@ -41,6 +41,7 @@
<ItemGroup>
<Compile Include="$(ComponentsSharedSourceRoot)src\CacheHeaderSettings.cs" Link="Shared\CacheHeaderSettings.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="Circuits" />
<Compile Include="$(ComponentsSharedSourceRoot)src\ElementReferenceJsonConverter.cs" />
<Compile Include="..\..\Shared\src\BrowserNavigationManagerInterop.cs" />
<Compile Include="..\..\Shared\src\JsonSerializerOptionsProvider.cs" />

View File

@ -1,24 +1,32 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using System.Text;
using System.Text.Json;
using Xunit;
namespace Microsoft.AspNetCore.Components
{
public class ElementReferenceTest
public class ElementReferenceJsonConverterTest
{
private readonly ElementReferenceJsonConverter Converter = new ElementReferenceJsonConverter();
[Fact]
public void Serializing_Works()
{
// Arrange
var elementReference = ElementReference.CreateWithUniqueId();
var expected = $"{{\"__internalId\":\"{elementReference.Id}\"}}";
var memoryStream = new MemoryStream();
var writer = new Utf8JsonWriter(memoryStream);
// Act
var json = JsonSerializer.Serialize(elementReference, JsonSerializerOptionsProvider.Options);
Converter.Write(writer, elementReference, new JsonSerializerOptions());
writer.Flush();
// Assert
var json = Encoding.UTF8.GetString(memoryStream.ToArray());
Assert.Equal(expected, json);
}
@ -28,9 +36,12 @@ namespace Microsoft.AspNetCore.Components
// Arrange
var id = ElementReference.CreateWithUniqueId().Id;
var json = $"{{\"__internalId\":\"{id}\"}}";
var bytes = Encoding.UTF8.GetBytes(json);
var reader = new Utf8JsonReader(bytes);
reader.Read();
// Act
var elementReference = JsonSerializer.Deserialize<ElementReference>(json, JsonSerializerOptionsProvider.Options);
var elementReference = Converter.Read(ref reader, typeof(ElementReference), new JsonSerializerOptions());
// Assert
Assert.Equal(id, elementReference.Id);
@ -45,9 +56,12 @@ namespace Microsoft.AspNetCore.Components
@$"{{
""__internalId"": ""{id}""
}}";
var bytes = Encoding.UTF8.GetBytes(json);
var reader = new Utf8JsonReader(bytes);
reader.Read();
// Act
var elementReference = JsonSerializer.Deserialize<ElementReference>(json, JsonSerializerOptionsProvider.Options);
var elementReference = Converter.Read(ref reader, typeof(ElementReference), new JsonSerializerOptions());
// Assert
Assert.Equal(id, elementReference.Id);
@ -58,9 +72,15 @@ namespace Microsoft.AspNetCore.Components
{
// Arrange
var json = "{\"id\":\"some-value\"}";
var bytes = Encoding.UTF8.GetBytes(json);
// Act
var ex = Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<ElementReference>(json, JsonSerializerOptionsProvider.Options));
var ex = Assert.Throws<JsonException>(() =>
{
var reader = new Utf8JsonReader(bytes);
reader.Read();
Converter.Read(ref reader, typeof(ElementReference), new JsonSerializerOptions());
});
// Assert
Assert.Equal("Unexpected JSON property 'id'.", ex.Message);
@ -71,9 +91,15 @@ namespace Microsoft.AspNetCore.Components
{
// Arrange
var json = "{}";
var bytes = Encoding.UTF8.GetBytes(json);
// Act
var ex = Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<ElementReference>(json, JsonSerializerOptionsProvider.Options));
var ex = Assert.Throws<JsonException>(() =>
{
var reader = new Utf8JsonReader(bytes);
reader.Read();
Converter.Read(ref reader, typeof(ElementReference), new JsonSerializerOptions());
});
// Assert
Assert.Equal("__internalId is required.", ex.Message);

View File

@ -0,0 +1,52 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.AspNetCore.Components
{
internal sealed class ElementReferenceJsonConverter : JsonConverter<ElementReference>
{
private static readonly JsonEncodedText IdProperty = JsonEncodedText.Encode("__internalId");
public override ElementReference Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string id = null;
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(IdProperty.EncodedUtf8Bytes))
{
reader.Read();
id = reader.GetString();
}
else
{
throw new JsonException($"Unexpected JSON property '{reader.GetString()}'.");
}
}
else
{
throw new JsonException($"Unexcepted JSON Token {reader.TokenType}.");
}
}
if (id is null)
{
throw new JsonException("__internalId is required.");
}
return new ElementReference(id);
}
public override void Write(Utf8JsonWriter writer, ElementReference value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(IdProperty, value.Id);
writer.WriteEndObject();
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@
"devDependencies": {
"@aspnet/signalr": "link:../../SignalR/clients/ts/signalr",
"@aspnet/signalr-protocol-msgpack": "link:../../SignalR/clients/ts/signalr-protocol-msgpack",
"@dotnet/jsinterop": "https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview8.19367.2.tgz",
"@dotnet/jsinterop": "https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview9.19415.3.tgz",
"@types/emscripten": "0.0.31",
"@types/jest": "^24.0.6",
"@types/jsdom": "11.0.6",

View File

@ -152,9 +152,9 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@dotnet/jsinterop@https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview8.19367.2.tgz":
version "3.0.0-preview8.19367.2"
resolved "https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview8.19367.2.tgz#885d87c9406ad0bbce878ff041d50342d03b2c86"
"@dotnet/jsinterop@https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview9.19415.3.tgz":
version "3.0.0-preview9.19415.3"
resolved "https://dotnet.myget.org/F/aspnetcore-dev/npm/@dotnet/jsinterop/-/@dotnet/jsinterop-3.0.0-preview9.19415.3.tgz#f44f482897c612e8d174b8f6d8795d2cda75d643"
"@jest/console@^24.7.1":
version "24.7.1"

View File

@ -8,11 +8,13 @@
<Reference Include="Microsoft.AspNetCore.Components" />
<Reference Include="Microsoft.AspNetCore.Components.Forms" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
<Reference Include="Microsoft.JSInterop" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<Compile Include="Microsoft.AspNetCore.Components.Web.netcoreapp3.0.cs" />
<Reference Include="Microsoft.AspNetCore.Components" />
<Reference Include="Microsoft.AspNetCore.Components.Forms" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
<Reference Include="Microsoft.JSInterop" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
@ -14,10 +14,7 @@
<Reference Include="Microsoft.AspNetCore.Components" />
<Reference Include="Microsoft.AspNetCore.Components.Forms" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\src\JsonSerializerOptionsProvider.cs" />
<Reference Include="Microsoft.JSInterop" />
</ItemGroup>
</Project>

View File

@ -11,7 +11,7 @@
<Reference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Html.Abstractions" />
<Reference Include="Microsoft.Extensions.WebEncoders" />
<Reference Include="Microsoft.AspNetCore.Components" />
<Reference Include="Microsoft.AspNetCore.Components.Authorization" />
<Reference Include="Microsoft.AspNetCore.Components.Web" />
</ItemGroup>
</Project>

View File

@ -22,8 +22,8 @@ Microsoft.AspNetCore.Mvc.ViewComponent</Description>
<Reference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Html.Abstractions" />
<Reference Include="Microsoft.Extensions.WebEncoders" />
<Reference Include="Microsoft.AspNetCore.Components" />
<Reference Include="Microsoft.AspNetCore.Components.Authorization" />
<Reference Include="Microsoft.AspNetCore.Components.Web" />
</ItemGroup>
</Project>