Add nullable to JSInterop (#22326)

This commit is contained in:
Pranav K 2020-06-09 22:39:01 -07:00 committed by GitHub
parent e1fab3098b
commit c58ab9247c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 88 additions and 86 deletions

View File

@ -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" />

View File

@ -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; } }
}
}

View File

@ -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; } }
}
}

View File

@ -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
{

View File

@ -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; }

View File

@ -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"/>.

View File

@ -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)!;
}
}
}

View File

@ -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))!;
});
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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'">

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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
{

View File

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>$(DefaultNetCoreTargetFramework);net472</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

View File

@ -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();
}