最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Blazor to Javascript byte array interop - Stack Overflow

programmeradmin1浏览0评论

I am trying to pass an array of byte from Blazor Client to a javascript function:

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

On Javascript side:

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) outputs the following:

Which seems to me a base64 string representation of my binary data. According wikipedia the size is incremented approximately by 33% going from byte array to base64 string representation, and this is true for this case: 131072 * 1.33 ~ 174764

My questions then are:

  • How to pass and receive a byte array from Blazor (C#) to Javascript without converting it to a string
  • If the previous is not possible, what is the best way to convert the base64 string to byte array on Javascript side.

I am trying to pass an array of byte from Blazor Client to a javascript function:

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

On Javascript side:

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) outputs the following:

Which seems to me a base64 string representation of my binary data. According wikipedia the size is incremented approximately by 33% going from byte array to base64 string representation, and this is true for this case: 131072 * 1.33 ~ 174764

My questions then are:

  • How to pass and receive a byte array from Blazor (C#) to Javascript without converting it to a string
  • If the previous is not possible, what is the best way to convert the base64 string to byte array on Javascript side.
Share Improve this question asked Nov 12, 2020 at 11:34 SturmSturm 4,12410 gold badges55 silver badges84 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I gave it another go:

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 requires a return it appears, therefore int in the template arguments. Instead of this probably a reference to the object has to be returned to dispose it. I would appreciate if someone can ment on this (will javascript free that memory when the byte array is not used anymore?).

First tests show an improvement of a factor of 50!

When you are using the interop service, the documentation says:

InvokeAsync takes an identifier for the JavaScript function that you wish to invoke along with any number of JSON-serializable arguments.

So what you observe is the serialization of your byte array into a base64 string, which is the out-of-the-box behavior. So, you are right. I haven't spotted a way to influence the serialization behavior of the JSInterop service.

The Blazer framework in .NET 5 offers you a way to skip the serialization overhead: IJSUnmarshalledRuntime.

But, in my experiments, it can't handle a byte array or any arrays at all.

To answer your second question, have a look at this discussion.

Convert base64 string to ArrayBuffer

发布评论

评论列表(0)

  1. 暂无评论