javascriptblazorjavascript-interop

Need C# JSImport async signature interop example to match async Javascript method - Blazor


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


Solution

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