Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the ability to specify custom JsonSerializerOptions #22317

Closed
9 changes: 9 additions & 0 deletions src/Components/Server/test/ProtectedBrowserStorageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,15 @@ public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToke

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args)
=> InvokeAsync<TValue>(identifier, cancellationToken: CancellationToken.None, args: args);

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object[] args)
{
Invocations.Add((identifier, args));
return (ValueTask<TValue>)NextInvocationResult;
}

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object[] args)
=> InvokeAsync<TValue>(identifier, cancellationToken: CancellationToken.None, jsonSerializerOptions: jsonSerializerOptions, args: args);
}

class TestProtectedBrowserStorage : ProtectedBrowserStorage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,18 @@ public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToke
return new ValueTask<TValue>((TValue)GetInvocationResult(identifier));
}

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object[] args)
{
PastInvocations.Add((identifier, args));
return new ValueTask<TValue>((TValue)GetInvocationResult(identifier));
}

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object[] args)
{
PastInvocations.Add((identifier, args));
return new ValueTask<TValue>((TValue)GetInvocationResult(identifier));
}

private object GetInvocationResult(string identifier)
{
switch (identifier)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Security.Claims;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
Expand Down Expand Up @@ -706,6 +707,18 @@ public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToke
LastInvocation = (identifier, args);
return default;
}

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object[] args)
{
LastInvocation = (identifier, args);
return default;
}

public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object[] args)
{
LastInvocation = (identifier, args);
return default;
}
}

public class TestRemoteAuthenticatorView : RemoteAuthenticatorViewCore<RemoteAuthenticationState>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text.Json;

namespace Microsoft.JSInterop
{
Expand All @@ -18,5 +19,15 @@ public interface IJSInProcessObjectReference : IJSObjectReference, IDisposable
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
TValue Invoke<TValue>(string identifier, params object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function synchronously.
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>someScope.someFunction</c> on the target instance.</param>
/// <param name="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
TValue Invoke<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, params object?[]? args);
}
}
12 changes: 12 additions & 0 deletions src/JSInterop/Microsoft.JSInterop/src/IJSInProcessRuntime.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// 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.Text.Json;

namespace Microsoft.JSInterop
{
/// <summary>
Expand All @@ -16,5 +18,15 @@ public interface IJSInProcessRuntime : IJSRuntime
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TResult"/> obtained by JSON-deserializing the return value.</returns>
TResult Invoke<TResult>(string identifier, params object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function synchronously.
/// </summary>
/// <typeparam name="TResult">The JSON-serializable return type.</typeparam>
/// <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="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TResult"/> obtained by JSON-deserializing the return value.</returns>
TResult Invoke<TResult>(string identifier, JsonSerializerOptions jsonSerializerOptions, params object?[]? args);
}
}
29 changes: 29 additions & 0 deletions src/JSInterop/Microsoft.JSInterop/src/IJSObjectReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -37,5 +38,33 @@ public interface IJSObjectReference : IAsyncDisposable
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function asynchronously.
/// <para>
/// <see cref="JSRuntime"/> will apply timeouts to this operation based on the value configured in <see cref="JSRuntime.DefaultAsyncTimeout"/>. To dispatch a call with a different, or no timeout,
/// consider using <see cref="InvokeAsync{TValue}(string, CancellationToken, object[])" />.
/// </para>
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>someScope.someFunction</c> on the target instance.</param>
/// <param name="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function asynchronously.
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>someScope.someFunction</c> on the target instance.</param>
/// <param name="cancellationToken">
/// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <param name="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object?[]? args);
}
}
29 changes: 29 additions & 0 deletions src/JSInterop/Microsoft.JSInterop/src/IJSRuntime.cs
Original file line number Diff line number Diff line change
@@ -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.Text.Json;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -36,5 +37,33 @@ public interface IJSRuntime
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function asynchronously.
/// <para>
/// <see cref="JSRuntime"/> will apply timeouts to this operation based on the value configured in <see cref="JSRuntime.DefaultAsyncTimeout"/>. To dispatch a call with a different timeout, or no timeout,
/// consider using <see cref="InvokeAsync{TValue}(string, CancellationToken, JsonSerializerOptions, object[])" />.
/// </para>
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <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="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object?[]? args);

/// <summary>
/// Invokes the specified JavaScript function asynchronously.
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <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="cancellationToken">
/// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <param name="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object?[]? args);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +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.Implementation
{
Expand Down Expand Up @@ -30,6 +30,14 @@ public TValue Invoke<TValue>(string identifier, params object?[]? args)
return _jsRuntime.Invoke<TValue>(identifier, Id, args);
}

/// <inheritdoc />
public TValue Invoke<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, params object?[]? args)
{
ThrowIfDisposed();

return _jsRuntime.Invoke<TValue>(identifier, Id, jsonSerializerOptions, args);
}

/// <inheritdoc />
public void Dispose()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -49,6 +50,22 @@ public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToke
return _jsRuntime.InvokeAsync<TValue>(Id, identifier, cancellationToken, args);
}

/// <inheritdoc />
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, JsonSerializerOptions jsonSerializerOptions, object?[]? args)
{
ThrowIfDisposed();

return _jsRuntime.InvokeAsync<TValue>(Id, identifier, jsonSerializerOptions, args);
}

/// <inheritdoc />
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, JsonSerializerOptions jsonSerializerOptions, object?[]? args)
{
ThrowIfDisposed();

return _jsRuntime.InvokeAsync<TValue>(Id, identifier, cancellationToken, jsonSerializerOptions, args);
}

/// <inheritdoc />
public async ValueTask DisposeAsync()
{
Expand Down
20 changes: 15 additions & 5 deletions src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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;
using Microsoft.JSInterop.Implementation;
using Microsoft.JSInterop.Infrastructure;
Expand All @@ -23,11 +22,11 @@ protected JSInProcessRuntime()
id => new JSInProcessObjectReference(this, id)));
}

internal TValue Invoke<TValue>(string identifier, long targetInstanceId, params object?[]? args)
internal TValue Invoke<TValue>(string identifier, long targetInstanceId, JsonSerializerOptions jsonSerializerOptions, params object?[]? args)
{
var resultJson = InvokeJS(
identifier,
JsonSerializer.Serialize(args, JsonSerializerOptions),
JsonSerializer.Serialize(args, jsonSerializerOptions),
JSCallResultTypeHelper.FromGeneric<TValue>(),
targetInstanceId);

Expand All @@ -39,7 +38,7 @@ internal TValue Invoke<TValue>(string identifier, long targetInstanceId, params
return default!;
}

return JsonSerializer.Deserialize<TValue>(resultJson, JsonSerializerOptions)!;
return JsonSerializer.Deserialize<TValue>(resultJson, jsonSerializerOptions)!;
}

/// <summary>
Expand All @@ -50,7 +49,18 @@ internal TValue Invoke<TValue>(string identifier, long targetInstanceId, params
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
public TValue Invoke<TValue>(string identifier, params object?[]? args)
=> Invoke<TValue>(identifier, 0, args);
=> Invoke<TValue>(identifier, 0, JsonSerializerOptions, args);

/// <summary>
/// Invokes the specified JavaScript function synchronously.
/// </summary>
/// <typeparam name="TResult">The JSON-serializable return type.</typeparam>
/// <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="jsonSerializerOptions">JSON serialization options to use during serialization/deserialization of the args and return value.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TResult"/> obtained by JSON-deserializing the return value.</returns>
public TResult Invoke<TResult>(string identifier, JsonSerializerOptions jsonSerializerOptions, params object?[]? args)
=> Invoke<TResult>(identifier, 0, jsonSerializerOptions, args);

/// <summary>
/// Performs a synchronous function invocation.
Expand Down
Loading