1

In Blazor, Core 7, I don't know how to create a JSImport signature to match an async javascript method. Here's an example of the Javascript method:

export async function DoSomething(data)
{
    // do work
    return result
}

the following C# signature doesn't compile because of the async and Task

    // assume ImportAsync has already been called
    [JSImport("DoSomething", "MyModule/DoSomething.js")]
    internal static async partial Task<byte[]> DoSomething(byte[] data);

The microsoft literature was no help and there's no async examples here: https://github.com/pavelsavara/dotnet-wasm-todo-mvc

Am I supposed to use a callback? That would seem rather primitive and destroys the async model

Sean
  • 2,531
  • 2
  • 17
  • 17

1 Answers1

2

The import

[JSImport("getMessage", "SampleJS")]
[return: JSMarshalAs<JSType.Promise<JSType.Any>>()]
internal static partial Task<object> 
  GetWelcomeMessage([JSMarshalAs<JSType.Array<JSType.Number>>] byte[] bytes);

JS module

export async function getMessage(data) {
  console.log(data)
  return await new Promise((resolve) => {
    setTimeout(() => {
      resolve(data);
    }, 2000);
  });
}

This just logs the data (bytes) received, waits 2s and returns the same data.

Usage

byte[] sampleData = Encoding.UTF8.GetBytes("Hello from C#");
object? result = await GetWelcomeMessage(sampleData);
if (result is byte[] bytes)
{
    message = Encoding.UTF8.GetString(bytes);
    Console.WriteLine($"Got {message} from {result.GetType()}");
}
Sean
  • 2,531
  • 2
  • 17
  • 17
Mister Magoo
  • 7,452
  • 1
  • 20
  • 35
  • Oh yeah, it seems `byte[]` is not allowed - I had only tried string – Mister Magoo Jan 21 '23 at 00:28
  • I have provided a more complete working answer – Mister Magoo Jan 21 '23 at 01:39
  • There is a table of data type mappings - I don't really understand it but you might [here](https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/import-export-interop?view=aspnetcore-7.0#:~:text=The%20following%20table%20indicates%20the%20supported%20type%20mappings.) – Mister Magoo Jan 21 '23 at 01:41
  • Most excellent voodoo Mister Magoo. I would never have figured that out, thank you. Though, when I think about the purpose of JSImport, I'm compelled to believe there's a bidirectional MemoryView parameter approach instead of sending and receiving byte[]. Unfortunately, when I try to impose MemoryView, the Javascript doesn't know what to do with it, and I don't know how to turn it into an Uint8Array for my javascript. Would you be so generous as to alter your example to work with MemoryView? – Sean Jan 21 '23 at 03:54
  • I don't think that is possible, maybe someone else can figure it out – Mister Magoo Jan 21 '23 at 13:03
  • Figured it out and modified your answer accordingly. It's only for sending MemoryViews, not receiving. Still working on a leaner solution for the returned value. – Sean Jan 21 '23 at 16:34
  • I'm not really all that comfortable with you changing my answer, but I cannot stop it, so I'll just walk away. – Mister Magoo Jan 21 '23 at 16:42
  • I apologize, I have reverted my edits to your post. My edits reflected the MemoryView utilization I spoke of earlier, but I didn't want to create another answer that would take the credit away from you. You're right though, I should've asked first. I will create my own answer. – Sean Jan 21 '23 at 17:44