【问题标题】:Blazor to Javascript byte array interopBlazor 到 Javascript 字节数组互操作
【发布时间】:2021-02-24 09:54:58
【问题描述】:

我正在尝试将 byte 的数组从 Blazor 客户端传递给 javascript 函数:

private async void ShowImage()
{
    SelectedImageBytes = await GetImageData();
    if (SelectedImageBytes.Any())
    {
        ReceivedDataLength = SelectedImageBytes.Length;
        //ReceivedDataLength is 131072, which is correct
        JS.InvokeVoidAsync("JS.setImage", SelectedImageBytes, 256, 256);
        
    }

    StateHasChanged();
}

在 Javascript 方面:

function setImage(data, width, height)
{
    console.log("On Javascript I have received an array of " + data.length);
    //data.length is 174764
    console.log(data);

    //...
}

console.log(data) 输出以下内容:

在我看来,这似乎是我的二进制数据的 base64 字符串表示。根据 wikipedia,从字节数组到 base64 字符串表示的大小大约增加了 33%,在这种情况下确实如此:131072 * 1.33 ~ 174764

那么我的问题是:

  • 如何在不将其转换为字符串的情况下从 Blazor (C#) 向 Javascript 传递和接收字节数组
  • 如果前面的方法不可行,那么在 Javascript 端将 base64 字符串转换为字节数组的最佳方法是什么。

【问题讨论】:

    标签: javascript arrays blazor


    【解决方案1】:

    我又试了一次:

    C#

    public void CallJsUnMarshalled()
    {
        var unmarshalledRuntime = (IJSUnmarshalledRuntime)JS;
        unmarshalledRuntime.InvokeUnmarshalled<byte[], int>("JsFunctions.MyFunctionUnmarshalled", MyBytes);
    }
    

    Javascript:

    function MyFunctionUnmarshalled(bytes)
    {
        const dataPtr = Blazor.platform.getArrayEntryPtr(bytes, 0, 4);
        const length = Blazor.platform.getArrayLength(bytes);
        var shorts = new Int16Array(Module.HEAPU8.buffer, dataPtr, length);
        return 0;
    }
    

    InvokeUnmarshalled 需要返回它出现,因此 int 在模板参数中。取而代之的是,可能必须返回对该对象的引用才能处理它。如果有人可以对此发表评论,我将不胜感激(当不再使用字节数组时,javascript 会释放该内存吗?)。

    第一次测试显示提高了 50 倍!

    【讨论】:

      【解决方案2】:

      当您使用互操作服务时,documentation 会说:

      InvokeAsync 采用您希望调用的 JavaScript 函数的标识符以及任意数量的 JSON-serializable 参数。

      因此,您观察到的是将字节数组序列化为 base64 字符串,这是开箱即用的行为。所以,你是对的。我还没有发现影响 JSInterop 服务的序列化行为的方法。

      .NET 5 中的 Blazer 框架为您提供了一种跳过序列化开销的方法:IJSUnmarshalledRuntime

      但是,在我的实验中,它根本无法处理字节数组或任何数组。

      要回答您的第二个问题,请查看此讨论。

      Convert base64 string to ArrayBuffer

      【讨论】:

      • 看起来很有希望。您知道它为什么不起作用吗?
      • 我猜数组不是原生 javascript 类型,不像数字或字符串。它适用于由数字、字符串和由数字和字符串组成的嵌套对象组成的对象。 :) 似乎不是数组,而是一种标识符(一个让我想起 C 指针的数字)被注入到 javascript 方法中。我可以想象这个数字以及对其他 javascript 方法的一些调用可能会将您带到数组附近。
      • 我按照您对 IJSUnmarshalledRuntime 的提示进行了操作,谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2010-11-02
      • 2020-08-09
      • 2021-03-07
      • 1970-01-01
      • 2011-12-29
      相关资源
      最近更新 更多