Add nullable to JSInterop (#22326)
This commit is contained in:
parent
e1fab3098b
commit
c58ab9247c
|
|
@ -3,6 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(DotNetBuildFromSource)' == 'true'">$(DefaultNetCoreTargetFramework)</TargetFrameworks>
|
||||
<Nullable>annotations</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
<Compile Include="Microsoft.JSInterop.netstandard2.0.cs" />
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ namespace Microsoft.JSInterop
|
|||
public abstract partial class JSInProcessRuntime : Microsoft.JSInterop.JSRuntime, Microsoft.JSInterop.IJSInProcessRuntime, Microsoft.JSInterop.IJSRuntime
|
||||
{
|
||||
protected JSInProcessRuntime() { }
|
||||
protected abstract string InvokeJS(string identifier, string argsJson);
|
||||
protected abstract string? InvokeJS(string identifier, string? argsJson);
|
||||
[return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
|
||||
public TValue Invoke<TValue>(string identifier, params object[] args) { throw null; }
|
||||
}
|
||||
public static partial class JSInProcessRuntimeExtensions
|
||||
|
|
@ -42,15 +43,16 @@ namespace Microsoft.JSInterop
|
|||
{
|
||||
public JSInvokableAttribute() { }
|
||||
public JSInvokableAttribute(string identifier) { }
|
||||
public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string? Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public abstract partial class JSRuntime : Microsoft.JSInterop.IJSRuntime
|
||||
{
|
||||
protected JSRuntime() { }
|
||||
protected System.TimeSpan? DefaultAsyncTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected internal System.Text.Json.JsonSerializerOptions JsonSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string argsJson);
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string? argsJson);
|
||||
protected internal abstract void EndInvokeDotNet(Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, in Microsoft.JSInterop.Infrastructure.DotNetInvocationResult invocationResult);
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute]
|
||||
public System.Threading.Tasks.ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args) { throw null; }
|
||||
public System.Threading.Tasks.ValueTask<TValue> InvokeAsync<TValue>(string identifier, System.Threading.CancellationToken cancellationToken, object[] args) { throw null; }
|
||||
}
|
||||
|
|
@ -74,7 +76,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
public static void BeginInvokeDotNet(Microsoft.JSInterop.JSRuntime jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { }
|
||||
public static void EndInvokeJS(Microsoft.JSInterop.JSRuntime jsRuntime, string arguments) { }
|
||||
public static string Invoke(Microsoft.JSInterop.JSRuntime jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { throw null; }
|
||||
public static string? Invoke(Microsoft.JSInterop.JSRuntime jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { throw null; }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public readonly partial struct DotNetInvocationInfo
|
||||
|
|
@ -92,11 +94,11 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
private readonly object _dummy;
|
||||
private readonly int _dummyPrimitive;
|
||||
public DotNetInvocationResult(System.Exception exception, string errorKind) { throw null; }
|
||||
public DotNetInvocationResult(object result) { throw null; }
|
||||
public string ErrorKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public DotNetInvocationResult(System.Exception exception, string? errorKind) { throw null; }
|
||||
public DotNetInvocationResult(object? result) { throw null; }
|
||||
public string? ErrorKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public System.Exception? Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public object? Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public bool Success { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.JSInterop
|
|||
public abstract partial class JSInProcessRuntime : Microsoft.JSInterop.JSRuntime, Microsoft.JSInterop.IJSInProcessRuntime, Microsoft.JSInterop.IJSRuntime
|
||||
{
|
||||
protected JSInProcessRuntime() { }
|
||||
protected abstract string InvokeJS(string identifier, string argsJson);
|
||||
protected abstract string? InvokeJS(string identifier, string? argsJson);
|
||||
public TValue Invoke<TValue>(string identifier, params object[] args) { throw null; }
|
||||
}
|
||||
public static partial class JSInProcessRuntimeExtensions
|
||||
|
|
@ -42,15 +42,16 @@ namespace Microsoft.JSInterop
|
|||
{
|
||||
public JSInvokableAttribute() { }
|
||||
public JSInvokableAttribute(string identifier) { }
|
||||
public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string? Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public abstract partial class JSRuntime : Microsoft.JSInterop.IJSRuntime
|
||||
{
|
||||
protected JSRuntime() { }
|
||||
protected System.TimeSpan? DefaultAsyncTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected internal System.Text.Json.JsonSerializerOptions JsonSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string argsJson);
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string? argsJson);
|
||||
protected internal abstract void EndInvokeDotNet(Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, in Microsoft.JSInterop.Infrastructure.DotNetInvocationResult invocationResult);
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute]
|
||||
public System.Threading.Tasks.ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args) { throw null; }
|
||||
public System.Threading.Tasks.ValueTask<TValue> InvokeAsync<TValue>(string identifier, System.Threading.CancellationToken cancellationToken, object[] args) { throw null; }
|
||||
}
|
||||
|
|
@ -74,7 +75,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
public static void BeginInvokeDotNet(Microsoft.JSInterop.JSRuntime jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { }
|
||||
public static void EndInvokeJS(Microsoft.JSInterop.JSRuntime jsRuntime, string arguments) { }
|
||||
public static string Invoke(Microsoft.JSInterop.JSRuntime jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { throw null; }
|
||||
public static string? Invoke(Microsoft.JSInterop.JSRuntime jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string argsJson) { throw null; }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public readonly partial struct DotNetInvocationInfo
|
||||
|
|
@ -92,11 +93,11 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
private readonly object _dummy;
|
||||
private readonly int _dummyPrimitive;
|
||||
public DotNetInvocationResult(System.Exception exception, string errorKind) { throw null; }
|
||||
public DotNetInvocationResult(object result) { throw null; }
|
||||
public string ErrorKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public DotNetInvocationResult(System.Exception exception, string? errorKind) { throw null; }
|
||||
public DotNetInvocationResult(object? result) { throw null; }
|
||||
public string? ErrorKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public System.Exception? Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public object? Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public bool Success { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Microsoft.JSInterop
|
|||
{
|
||||
private readonly TValue _value;
|
||||
private long _objectId;
|
||||
private JSRuntime _jsRuntime;
|
||||
private JSRuntime? _jsRuntime;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="DotNetObjectReference{TValue}" />.
|
||||
|
|
@ -57,7 +57,7 @@ namespace Microsoft.JSInterop
|
|||
}
|
||||
}
|
||||
|
||||
internal JSRuntime JSRuntime
|
||||
internal JSRuntime? JSRuntime
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
/// <param name="invocationInfo">The <see cref="DotNetInvocationInfo"/>.</param>
|
||||
/// <param name="argsJson">A JSON representation of the parameters.</param>
|
||||
/// <returns>A JSON representation of the return value, or null.</returns>
|
||||
public static string Invoke(JSRuntime jsRuntime, in DotNetInvocationInfo invocationInfo, string argsJson)
|
||||
public static string? Invoke(JSRuntime jsRuntime, in DotNetInvocationInfo invocationInfo, string argsJson)
|
||||
{
|
||||
// This method doesn't need [JSInvokable] because the platform is responsible for having
|
||||
// some way to dispatch calls here. The logic inside here is the thing that checks whether
|
||||
// the targeted method has [JSInvokable]. It is not itself subject to that restriction,
|
||||
// because there would be nobody to police that. This method *is* the police.
|
||||
|
||||
IDotNetObjectReference targetInstance = default;
|
||||
IDotNetObjectReference? targetInstance = default;
|
||||
if (invocationInfo.DotNetObjectId != default)
|
||||
{
|
||||
targetInstance = jsRuntime.GetObjectReference(invocationInfo.DotNetObjectId);
|
||||
|
|
@ -75,9 +75,9 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
|
||||
var callId = invocationInfo.CallId;
|
||||
|
||||
object syncResult = null;
|
||||
ExceptionDispatchInfo syncException = null;
|
||||
IDotNetObjectReference targetInstance = null;
|
||||
object? syncResult = null;
|
||||
ExceptionDispatchInfo? syncException = null;
|
||||
IDotNetObjectReference? targetInstance = null;
|
||||
try
|
||||
{
|
||||
if (invocationInfo.DotNetObjectId != default)
|
||||
|
|
@ -126,7 +126,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
}
|
||||
}
|
||||
|
||||
private static object InvokeSynchronously(JSRuntime jsRuntime, in DotNetInvocationInfo callInfo, IDotNetObjectReference objectReference, string argsJson)
|
||||
private static object? InvokeSynchronously(JSRuntime jsRuntime, in DotNetInvocationInfo callInfo, IDotNetObjectReference? objectReference, string argsJson)
|
||||
{
|
||||
var assemblyName = callInfo.AssemblyName;
|
||||
var methodIdentifier = callInfo.MethodIdentifier;
|
||||
|
|
@ -168,14 +168,14 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
if (tie.InnerException != null)
|
||||
{
|
||||
ExceptionDispatchInfo.Capture(tie.InnerException).Throw();
|
||||
throw null; // unreached
|
||||
throw tie.InnerException; // Unreachable
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
internal static object[] ParseArguments(JSRuntime jsRuntime, string methodIdentifier, string arguments, Type[] parameterTypes)
|
||||
internal static object?[] ParseArguments(JSRuntime jsRuntime, string methodIdentifier, string arguments, Type[] parameterTypes)
|
||||
{
|
||||
if (parameterTypes.Length == 0)
|
||||
{
|
||||
|
|
@ -189,7 +189,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
throw new JsonException("Invalid JSON");
|
||||
}
|
||||
|
||||
var suppliedArgs = new object[parameterTypes.Length];
|
||||
var suppliedArgs = new object?[parameterTypes.Length];
|
||||
|
||||
var index = 0;
|
||||
while (index < parameterTypes.Length && reader.Read() && reader.TokenType != JsonTokenType.EndArray)
|
||||
|
|
@ -331,7 +331,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
|
||||
foreach (var method in invokableMethods)
|
||||
{
|
||||
var identifier = method.GetCustomAttribute<JSInvokableAttribute>(false).Identifier ?? method.Name;
|
||||
var identifier = method.GetCustomAttribute<JSInvokableAttribute>(false)!.Identifier ?? method.Name!;
|
||||
var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
|
||||
|
||||
if (result.ContainsKey(identifier))
|
||||
|
|
@ -360,7 +360,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
.Where(method => !method.ContainsGenericParameters && method.IsDefined(typeof(JSInvokableAttribute), inherit: false));
|
||||
foreach (var method in invokableMethods)
|
||||
{
|
||||
var identifier = method.GetCustomAttribute<JSInvokableAttribute>(false).Identifier ?? method.Name;
|
||||
var identifier = method.GetCustomAttribute<JSInvokableAttribute>(false)!.Identifier ?? method.Name;
|
||||
var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
|
||||
|
||||
if (result.ContainsKey(identifier))
|
||||
|
|
@ -400,7 +400,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
public AssemblyKey(Assembly assembly)
|
||||
{
|
||||
Assembly = assembly;
|
||||
AssemblyName = assembly.GetName().Name;
|
||||
AssemblyName = assembly.GetName().Name!;
|
||||
}
|
||||
|
||||
public AssemblyKey(string assemblyName)
|
||||
|
|
@ -409,7 +409,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
AssemblyName = assemblyName;
|
||||
}
|
||||
|
||||
public Assembly Assembly { get; }
|
||||
public Assembly? Assembly { get; }
|
||||
|
||||
public string AssemblyName { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
/// </summary>
|
||||
/// <param name="exception">The <see cref="System.Exception"/> that caused the failure.</param>
|
||||
/// <param name="errorKind">The error kind.</param>
|
||||
public DotNetInvocationResult(Exception exception, string errorKind)
|
||||
public DotNetInvocationResult(Exception exception, string? errorKind)
|
||||
{
|
||||
Result = default;
|
||||
Exception = exception ?? throw new ArgumentNullException(nameof(exception));
|
||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
/// Constructor for a successful invocation.
|
||||
/// </summary>
|
||||
/// <param name="result">The result.</param>
|
||||
public DotNetInvocationResult(object result)
|
||||
public DotNetInvocationResult(object? result)
|
||||
{
|
||||
Result = result;
|
||||
Exception = default;
|
||||
|
|
@ -35,17 +35,17 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
/// <summary>
|
||||
/// Gets the <see cref="System.Exception"/> that caused the failure.
|
||||
/// </summary>
|
||||
public Exception Exception { get; }
|
||||
public Exception? Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error kind.
|
||||
/// </summary>
|
||||
public string ErrorKind { get; }
|
||||
public string? ErrorKind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the result of a successful invocation.
|
||||
/// </summary>
|
||||
public object Result { get; }
|
||||
public object? Result { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the invocation succeeded, otherwise <see langword="false"/>.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
var instanceType = typeToConvert.GetGenericArguments()[0];
|
||||
var converterType = typeof(DotNetObjectReferenceJsonConverter<>).MakeGenericType(instanceType);
|
||||
|
||||
return (JsonConverter)Activator.CreateInstance(converterType, JSRuntime);
|
||||
return (JsonConverter)Activator.CreateInstance(converterType, JSRuntime)!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
private static ConcurrentDictionary<Type, ITcsResultSetter> _cachedResultSetters
|
||||
= new ConcurrentDictionary<Type, ITcsResultSetter>();
|
||||
|
||||
public static void SetTaskCompletionSourceResult(object taskCompletionSource, object result)
|
||||
public static void SetTaskCompletionSourceResult(object taskCompletionSource, object? result)
|
||||
=> CreateResultSetter(taskCompletionSource).SetResult(taskCompletionSource, result);
|
||||
|
||||
public static void SetTaskCompletionSourceException(object taskCompletionSource, Exception exception)
|
||||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
public static Type GetTaskCompletionSourceResultType(object taskCompletionSource)
|
||||
=> CreateResultSetter(taskCompletionSource).ResultType;
|
||||
|
||||
public static object GetTaskResult(Task task)
|
||||
public static object? GetTaskResult(Task task)
|
||||
{
|
||||
var getter = _cachedResultGetters.GetOrAdd(task.GetType(), taskInstanceType =>
|
||||
{
|
||||
|
|
@ -33,12 +33,12 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
return resultType == null
|
||||
? new VoidTaskResultGetter()
|
||||
: (ITaskResultGetter)Activator.CreateInstance(
|
||||
typeof(TaskResultGetter<>).MakeGenericType(resultType));
|
||||
typeof(TaskResultGetter<>).MakeGenericType(resultType))!;
|
||||
});
|
||||
return getter.GetResult(task);
|
||||
}
|
||||
|
||||
private static Type GetTaskResultType(Type taskType)
|
||||
private static Type? GetTaskResultType(Type taskType)
|
||||
{
|
||||
// It might be something derived from Task or Task<T>, so we have to scan
|
||||
// up the inheritance hierarchy to find the Task or Task<T>
|
||||
|
|
@ -57,23 +57,23 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
interface ITcsResultSetter
|
||||
{
|
||||
Type ResultType { get; }
|
||||
void SetResult(object taskCompletionSource, object result);
|
||||
void SetResult(object taskCompletionSource, object? result);
|
||||
void SetException(object taskCompletionSource, Exception exception);
|
||||
}
|
||||
|
||||
private interface ITaskResultGetter
|
||||
{
|
||||
object GetResult(Task task);
|
||||
object? GetResult(Task task);
|
||||
}
|
||||
|
||||
private class TaskResultGetter<T> : ITaskResultGetter
|
||||
{
|
||||
public object GetResult(Task task) => ((Task<T>)task).Result;
|
||||
public object? GetResult(Task task) => ((Task<T>)task).Result!;
|
||||
}
|
||||
|
||||
private class VoidTaskResultGetter : ITaskResultGetter
|
||||
{
|
||||
public object GetResult(Task task)
|
||||
public object? GetResult(Task task)
|
||||
{
|
||||
task.Wait(); // Throw if the task failed
|
||||
return null;
|
||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
public Type ResultType => typeof(T);
|
||||
|
||||
public void SetResult(object tcs, object result)
|
||||
public void SetResult(object tcs, object? result)
|
||||
{
|
||||
var typedTcs = (TaskCompletionSource<T>)tcs;
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
? resultT
|
||||
: (T)Convert.ChangeType(result, typeof(T));
|
||||
|
||||
typedTcs.SetResult(typedResult);
|
||||
typedTcs.SetResult(typedResult!);
|
||||
}
|
||||
|
||||
public void SetException(object tcs, Exception exception)
|
||||
|
|
@ -109,7 +109,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
{
|
||||
var resultType = tcsType.GetGenericArguments().Single();
|
||||
return (ITcsResultSetter)Activator.CreateInstance(
|
||||
typeof(TcsResultSetter<>).MakeGenericType(resultType));
|
||||
typeof(TcsResultSetter<>).MakeGenericType(resultType))!;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Microsoft.JSInterop
|
||||
|
|
@ -17,6 +18,7 @@ namespace Microsoft.JSInterop
|
|||
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
|
||||
/// <param name="args">JSON-serializable arguments.</param>
|
||||
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
|
||||
[return: MaybeNull]
|
||||
public TValue Invoke<TValue>(string identifier, params object[] args)
|
||||
{
|
||||
var resultJson = InvokeJS(identifier, JsonSerializer.Serialize(args, JsonSerializerOptions));
|
||||
|
|
@ -34,6 +36,6 @@ namespace Microsoft.JSInterop
|
|||
/// <param name="identifier">The identifier for the function to invoke.</param>
|
||||
/// <param name="argsJson">A JSON representation of the arguments.</param>
|
||||
/// <returns>A JSON representation of the result.</returns>
|
||||
protected abstract string InvokeJS(string identifier, string argsJson);
|
||||
protected abstract string? InvokeJS(string identifier, string? argsJson);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.JSInterop
|
|||
/// If not set, the identifier is taken from the name of the method. In this case the
|
||||
/// method name must be unique within the assembly.
|
||||
/// </summary>
|
||||
public string Identifier { get; }
|
||||
public string? Identifier { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="JSInvokableAttribute"/> without setting
|
||||
|
|
|
|||
|
|
@ -62,14 +62,16 @@ namespace Microsoft.JSInterop
|
|||
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
|
||||
/// <param name="args">JSON-serializable arguments.</param>
|
||||
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
|
||||
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args)
|
||||
public async ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args)
|
||||
{
|
||||
if (DefaultAsyncTimeout.HasValue)
|
||||
{
|
||||
return InvokeWithDefaultCancellation<TValue>(identifier, args);
|
||||
using var cts = new CancellationTokenSource(DefaultAsyncTimeout.Value);
|
||||
// We need to await here due to the using
|
||||
return await InvokeAsync<TValue>(identifier, cts.Token, args);
|
||||
}
|
||||
|
||||
return InvokeAsync<TValue>(identifier, CancellationToken.None, args);
|
||||
return await InvokeAsync<TValue>(identifier, CancellationToken.None, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -130,22 +132,13 @@ namespace Microsoft.JSInterop
|
|||
}
|
||||
}
|
||||
|
||||
private async ValueTask<T> InvokeWithDefaultCancellation<T>(string identifier, object[] args)
|
||||
{
|
||||
using (var cts = new CancellationTokenSource(DefaultAsyncTimeout.Value))
|
||||
{
|
||||
// We need to await here due to the using
|
||||
return await InvokeAsync<T>(identifier, cts.Token, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous function invocation.
|
||||
/// </summary>
|
||||
/// <param name="taskId">The identifier for the function invocation, or zero if no async callback is required.</param>
|
||||
/// <param name="identifier">The identifier for the function to invoke.</param>
|
||||
/// <param name="argsJson">A JSON representation of the arguments.</param>
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string argsJson);
|
||||
protected abstract void BeginInvokeJS(long taskId, string identifier, string? argsJson);
|
||||
|
||||
/// <summary>
|
||||
/// Completes an async JS interop call from JavaScript to .NET
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsPackable>true</IsPackable>
|
||||
<IsAspNetCoreApp>true</IsAspNetCoreApp>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.
|
||||
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
var json = $"{{\"__dotNetObject\":{objectId}}}";
|
||||
|
||||
// Act
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>>(json, JsonSerializerOptions);
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>>(json, JsonSerializerOptions)!;
|
||||
|
||||
// Assert
|
||||
Assert.Same(input, deserialized.Value);
|
||||
|
|
@ -100,7 +100,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
var json = $"[{{\"__dotNetObject\":{JSRuntime.TrackObjectReference(ref1)}}},{{\"__dotNetObject\":{JSRuntime.TrackObjectReference(ref2)}}}]";
|
||||
|
||||
// Act
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>[]>(json, JsonSerializerOptions);
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>[]>(json, JsonSerializerOptions)!;
|
||||
|
||||
// Assert
|
||||
Assert.Same(instance1, deserialized[0].Value);
|
||||
|
|
@ -121,7 +121,7 @@ namespace Microsoft.JSInterop.Infrastructure
|
|||
}}";
|
||||
|
||||
// Act
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>>(json, JsonSerializerOptions);
|
||||
var deserialized = JsonSerializer.Deserialize<DotNetObjectReference<TestModel>>(json, JsonSerializerOptions)!;
|
||||
|
||||
// Assert
|
||||
Assert.Same(input, deserialized.Value);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.JSInterop
|
|||
};
|
||||
|
||||
// Act
|
||||
var syncResult = runtime.Invoke<TestDTO>("test identifier 1", "arg1", 123, true);
|
||||
var syncResult = runtime.Invoke<TestDTO>("test identifier 1", "arg1", 123, true)!;
|
||||
var call = runtime.InvokeCalls.Single();
|
||||
|
||||
// Assert
|
||||
|
|
@ -80,7 +80,7 @@ namespace Microsoft.JSInterop
|
|||
"test identifier",
|
||||
DotNetObjectReference.Create(obj1),
|
||||
"some other arg",
|
||||
DotNetObjectReference.Create(obj2));
|
||||
DotNetObjectReference.Create(obj2))!;
|
||||
var call = runtime.InvokeCalls.Single();
|
||||
|
||||
// Assert
|
||||
|
|
@ -90,16 +90,16 @@ namespace Microsoft.JSInterop
|
|||
class TestDTO
|
||||
{
|
||||
public int IntValue { get; set; }
|
||||
public string StringValue { get; set; }
|
||||
public string? StringValue { get; set; }
|
||||
}
|
||||
|
||||
class TestJSInProcessRuntime : JSInProcessRuntime
|
||||
{
|
||||
public List<InvokeArgs> InvokeCalls { get; set; } = new List<InvokeArgs>();
|
||||
|
||||
public string NextResultJson { get; set; }
|
||||
public string? NextResultJson { get; set; }
|
||||
|
||||
protected override string InvokeJS(string identifier, string argsJson)
|
||||
protected override string? InvokeJS(string identifier, string? argsJson)
|
||||
{
|
||||
InvokeCalls.Add(new InvokeArgs { Identifier = identifier, ArgsJson = argsJson });
|
||||
return NextResultJson;
|
||||
|
|
@ -107,11 +107,11 @@ namespace Microsoft.JSInterop
|
|||
|
||||
public class InvokeArgs
|
||||
{
|
||||
public string Identifier { get; set; }
|
||||
public string ArgsJson { get; set; }
|
||||
public string? Identifier { get; set; }
|
||||
public string? ArgsJson { get; set; }
|
||||
}
|
||||
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson)
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson)
|
||||
=> throw new NotImplementedException("This test only covers sync calls");
|
||||
|
||||
protected internal override void EndInvokeDotNet(DotNetInvocationInfo invocationInfo, in DotNetInvocationResult invocationResult)
|
||||
|
|
|
|||
|
|
@ -322,14 +322,14 @@ namespace Microsoft.JSInterop
|
|||
|
||||
private class JSError
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
|
||||
private class TestPoco
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
class TestJSRuntime : JSRuntime
|
||||
|
|
@ -348,18 +348,18 @@ namespace Microsoft.JSInterop
|
|||
public class BeginInvokeAsyncArgs
|
||||
{
|
||||
public long AsyncHandle { get; set; }
|
||||
public string Identifier { get; set; }
|
||||
public string ArgsJson { get; set; }
|
||||
public string? Identifier { get; set; }
|
||||
public string? ArgsJson { get; set; }
|
||||
}
|
||||
|
||||
public class EndInvokeDotNetArgs
|
||||
{
|
||||
public string CallId { get; set; }
|
||||
public string? CallId { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public object ResultOrError { get; set; }
|
||||
public object? ResultOrError { get; set; }
|
||||
}
|
||||
|
||||
public Func<DotNetInvocationInfo, object> OnDotNetException { get; set; }
|
||||
public Func<DotNetInvocationInfo, object>? OnDotNetException { get; set; }
|
||||
|
||||
protected internal override void EndInvokeDotNet(DotNetInvocationInfo invocationInfo, in DotNetInvocationResult invocationResult)
|
||||
{
|
||||
|
|
@ -377,7 +377,7 @@ namespace Microsoft.JSInterop
|
|||
});
|
||||
}
|
||||
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson)
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson)
|
||||
{
|
||||
BeginInvokeCalls.Add(new BeginInvokeAsyncArgs
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(DefaultNetCoreTargetFramework);net472</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.JSInterop
|
|||
{
|
||||
internal class TestJSRuntime : JSRuntime
|
||||
{
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson)
|
||||
protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue