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

Blazor server side JS interoperability throws an exception when IJSInProcessObjectReference is passed to InvokeAsync #45440

Closed
1 task done
iam3yal opened this issue Dec 3, 2022 · 1 comment

Comments

@iam3yal
Copy link

iam3yal commented Dec 3, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Trying to receive an instance of an imported module through JSRuntime by calling InvokeAsync< IJSInProcessObjectReference> fails and throws the noted exception below.

Expected Behavior

To just work! when IJSObjectReference is passed it seems to work fine, for example:

@page "/"

<h1>Hello, world!</h1>

<button @onclick="Button_OnClick">Print</button>

@code
{
    [Inject]
    private IJSRuntime? JSRuntime { get; set; }
    
    private IJSObjectReference? JSRef { get; set; }
//
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        
        if (firstRender)
        {
            JSRef = await JSRuntime!.InvokeAsync<IJSObjectReference>("import", "/test.js");
        }
    }

    public void Button_OnClick()
        => JSRef?.InvokeVoidAsync("print");
}

Steps To Reproduce

  1. Create an empty Server Side Blazor app.
  2. Copy/paste the code below to Index.razor:
@page "/"

<h1>Hello, world!</h1>

<button @onclick="Button_OnClick">Print</button>

@code
{
    [Inject]
    private IJSRuntime? JSRuntime { get; set; }
    
    private IJSInProcessObjectReference? JSRef { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        
        if (firstRender)
        {
            JSRef = await JSRuntime!.InvokeAsync<IJSInProcessObjectReference>("import", "/test.js");
        }
    }

    public void Button_OnClick()
        => JSRef?.InvokeVoid("print");
}
  1. Create a test.js file inside the wwwroot and copy/paste this:
export function print()
{
    console.log("Hello Blazor")
}
  1. Run the application and you should see the exception being thrown once the page is rendered.

Exceptions (if any)

Error: Microsoft.JSInterop.JSException: An exception occurred executing JS interop: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.. See InnerException for more details.
 ---> System.NotSupportedException: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'.
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& state, Utf8JsonReader& reader, NotSupportedException ex)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCoreAsObject(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo, ReadStack& state)
   at System.Text.Json.JsonSerializer.Read[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo)
   at Microsoft.JSInterop.JSRuntime.EndInvokeJS(Int64 taskId, Boolean succeeded, Utf8JsonReader& jsonReader)
   --- End of inner exception stack trace ---
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
   at BlazorInterop.Pages.Index.OnAfterRenderAsync(Boolean firstRender) in /Users/eyal/Development/BlazorInterop/BlazorInterop/Pages/Index.razor:line 20
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

.NET Version

7.0.200

Anything else?

Tested versions: 7.0.200, 7.0.100

This happens regardless to development environment, I've tested it on the CLI and Rider.

dotnet --info:

.NET SDK:
 Version:   7.0.200
 Commit:    9ba3d6f3f0

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  13.0
 OS Platform: Darwin
 RID:         osx.13-arm64
 Base Path:   /usr/local/share/dotnet/sdk/7.0.200/

Host:
  Version:      7.0.0
  Architecture: arm64
  Commit:       d099f075e4

.NET SDKs installed:
  6.0.402 [/usr/local/share/dotnet/sdk]
  6.0.403 [/usr/local/share/dotnet/sdk]
  7.0.100-rc.2.22477.23 [/usr/local/share/dotnet/sdk]
  7.0.100 [/usr/local/share/dotnet/sdk]
  7.0.200 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0-rc.2.22476.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0-rc.2.22472.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  x64   [/usr/local/share/dotnet/x64]
    registered at [/etc/dotnet/install_location_x64]

Environment variables:
  Not set

global.json file:
  /Users/eyal/Development/Projects/RazorSharp/src/global.json

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
@iam3yal
Copy link
Author

iam3yal commented Dec 3, 2022

I tried it on .NET 6.0, read the error again and given my understanding about IJSInProcessObjectReference my intuition tells me that it's by design so to support both modes I should check whether it's server side and use IJSObjectReference as opposed to IJSInProcessObjectReference? it's documented here.

@iam3yal iam3yal closed this as completed Dec 3, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jan 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant