Unmarshalled JavaScript Isolation Code sample is incorrect
var unmarshalledRuntime = (IJSUnmarshalledRuntime)js;
var jsUnmarshalledReference = unmarshalledRuntime
.InvokeUnmarshalled<IJSUnmarshalledObjectReference>("unmarshalledInstance");
string helloWorldString = jsUnmarshalledReference.InvokeUnmarshalled<string, string>(
"helloWorld");
Error
There is no argument given that corresponds to the required formal parameter 'arg0' of 'IJSUnmarshalledObjectReference.InvokeUnmarshalled<T0, TResult>(string, T0)'
incorrect line 👇
string helloWorldString = jsUnmarshalledReference.InvokeUnmarshalled<string, string>(
"helloWorld");
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
Thanks @sps014 ... This was one of the examples that came in directly from the product unit. Let me take a look and get back to you either later today or on Monday morning.
@pranavkm ... I was playing around with this, and what I found in the framework tests here and here with this works. Could/should the example be more like that (example below :point_down:), or can you fix the example that we're showing? I couldn't make the existing example work on a first pass.
Whichever way the example goes, I have a few questions on unmarshalled interop coverage ...
int[]
and string
between .NET and JS don't match and can't be passed back (?) without additional work per https://github.com/dotnet/aspnetcore/issues/21492#issuecomment-637201926. I say "back" because when I did a test trying to pass back a string, it didn't break but didn't work either. Passing back a bool
or an int
worked fine.dispose
. Should that be included, as I have below?Here's an idea based on the framework tests ...
Inside the closing <body>
tag of wwwroot/index.html
...
<script>
function returnJSObjectReference() {
return {
dispose: function () {
DotNet.disposeJSObjectReference(this);
},
unmarshalledFunction: function (fields) {
const name = Blazor.platform.readStringField(fields, 0);
const year = Blazor.platform.readInt32Field(fields, 8);
return name === "Brigadier Alistair Gordon Lethbridge-Stewart" &&
year === 1968;
}
};
}
</script>
Pages/Hello.razor
...
@page "/hello"
@using System.Runtime.InteropServices
@using Microsoft.JSInterop
@inject IJSRuntime JS
<h1>Say Hello</h1>
<p>
@message
</p>
<p>
<button @onclick="SayHello">Say Hello</button>
</p>
<p>
<a href="https://www.doctorwho.tv">Doctor Who</a>
is a registered trademark of the <a href="https://www.bbc.com/">BBC</a>.
</p>
@code {
private string message;
private void SayHello()
{
var unmarshalledRuntime = (IJSUnmarshalledRuntime)JS;
var jsUnmarshalledReference = unmarshalledRuntime
.InvokeUnmarshalled<IJSUnmarshalledObjectReference>(
"returnJSObjectReference");
message = jsUnmarshalledReference.InvokeUnmarshalled<InteropStruct, bool>(
"unmarshalledFunction",
new InteropStruct
{
Name = "Brigadier Alistair Gordon Lethbridge-Stewart",
Year = 1968,
}).ToString();
}
[StructLayout(LayoutKind.Explicit)]
public struct InteropStruct
{
[FieldOffset(0)]
public string Name;
[FieldOffset(8)]
public int Year;
}
}
Thanks @guardrex
I modified so that I can easily import JS Lib , we no longer need to reference in index.html.
Most people would be happy if they do no require to reference js in index.html
Is this a the ideal way code to import ?
window.returnJSObjectReference = () =>
{
return {
dispose: function () {
DotNet.disposeJSObjectReference(this);
},
unmarshalledFunction: function (fields) {
const name = Blazor.platform.readStringField(fields, 0);
const year = Blazor.platform.readInt32Field(fields, 8);
return name === "Brigadier Alistair Gordon Lethbridge-Stewart" &&
year === 1968;
}
};
}
@page "/"
@using System.Runtime.InteropServices
@using Microsoft.JSInterop
@inject IJSRuntime JS
md5-495c3261f2ae8b705494ad5312125307
md5-e2cc5d4bf3cc75cb37b8992f6b1d272c
md5-2201867fbf306939021ca997df5474ac
md5-f5e64cbc6b2b5d1e77f0e8ffdf30833d
@code {
private string message;
protected override async Task OnInitializedAsync()
{
await JS.InvokeVoidAsync("import", "./my.js");
}
private async void SayHello()
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
var unmarshalledRuntime = (IJSUnmarshalledRuntime)JS;
var jsUnmarshalledReference = unmarshalledRuntime
.InvokeUnmarshalled<IJSUnmarshalledObjectReference>(
"returnJSObjectReference");
stopwatch.Start();
message = jsUnmarshalledReference.InvokeUnmarshalled<InteropStruct, bool>(
"unmarshalledFunction",
new InteropStruct
{
Name = "Brigadier Alistair Gordon Lethbridge-Stewart",
Year = 1968,
}).ToString();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
}
[StructLayout(LayoutKind.Explicit)]
public struct InteropStruct
{
[FieldOffset(0)]
public string Name;
[FieldOffset(8)]
public int Year;
}
}
Most people would be happy if they do no require to reference js in index.html
I was just taking the simplest approach to demonstrate the _Blazor_ concept.
ideal way code to import
We have a little bit of coverage at, which I think you saw there above the unmarshalled interop coverage ...
https://docs.microsoft.com/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0#blazor-javascript-isolation-and-object-references
... and I'll leave that to Pranav to remark further.
thanks once again @guardrex
Ping @pranavkm ... Sorry for the double-ping (or perhaps ur OOF right now). This is a live topic doc bug 🐞. I can fix it, but it's best if we discuss it first ... https://github.com/dotnet/AspNetCore.Docs/issues/20598#issuecomment-727663432. I can ask Safia to help if ur busy/out.
Most helpful comment
@pranavkm ... I was playing around with this, and what I found in the framework tests here and here with this works. Could/should the example be more like that (example below :point_down:), or can you fix the example that we're showing? I couldn't make the existing example work on a first pass.
Whichever way the example goes, I have a few questions on unmarshalled interop coverage ...
int[]
andstring
between .NET and JS don't match and can't be passed back (?) without additional work per https://github.com/dotnet/aspnetcore/issues/21492#issuecomment-637201926. I say "back" because when I did a test trying to pass back a string, it didn't break but didn't work either. Passing back abool
or anint
worked fine.dispose
. Should that be included, as I have below?Here's an idea based on the framework tests ...
Inside the closing
<body>
tag ofwwwroot/index.html
...Pages/Hello.razor
...