[英]Blazor: How to pass very long string from JS to C#?
I have a Blazor Component Library.我有一个 Blazor 组件库。 In the library my js code generates a huge string which is about 160 000 characters.
在库中,我的 js 代码生成了一个巨大的字符串,大约有 160 000 个字符。 Simplified JS below (actualy this is base64 string)
下面的简化 JS(实际上这是 base64 字符串)
export function showPrompt(message): Uint8Array {
alert(message);
let str = "";
for(let i = 0; i < 164232; i++)
str += "A";
return new TextEncoder().encode(str);
}
My C# code is:我的 C# 代码是:
async void CallJS() {
string? str = null;
IJSStreamReference? jsStream = await Prompt("After you will press ok, long string will be generated");
if (jsStream != null) {
using Stream referenceStream = await jsStream.OpenReadStreamAsync();
byte[] byteArray = new byte[referenceStream.Length];
int byteArrayCount = await referenceStream.ReadAsync(byteArray);
str = System.Text.Encoding.Default.GetString(byteArray, 0, byteArrayCount);
}
length = str?.Length ?? 0;
}
When I use this component in Blazor Server App, C# gets only 32 thousands chars.当我在 Blazor 服务器应用程序中使用此组件时,C# 仅获得 32,000 个字符。 As I understand this is due to Signal-R limitation.
据我了解,这是由于 Signal-R 的限制。 I've found this topic: Pass large JS blob to Blazor byte[] and tried the solution, but even with the code below, c# receives only 50 000 characters.
我找到了这个主题: 将大型 JS blob 传递给 Blazor byte[]并尝试了解决方案,但即使使用下面的代码,c# 也只收到 50 000 个字符。
services.AddSignalR(o => {
o.EnableDetailedErrors = true;
o.MaximumReceiveMessageSize = long.MaxValue;
});
How to pass a huge string from JS to C# in Blazor?如何在Blazor中将一个巨大的字符串从JS传给C#?
We hit the same problem - I think the problem is, that SignalR is chunking the message when using IJSStreamReference
if it is too big.我们遇到了同样的问题 - 我认为问题是,如果 SignalR 太大,则在使用
IJSStreamReference
时会将消息分块。 When you call await referenceStream.ReadAsync(byteArray);
当您调用
await referenceStream.ReadAsync(byteArray);
there is a posibillity that the Message isn't completely transfered yet.有可能消息尚未完全传输。
Try copying the referenceStream
to an MemoryStream
and call.ToArray() on it.尝试将
referenceStream
复制到MemoryStream
并在其上调用.ToArray()。
async void CallJS() {
string? str = null;
IJSStreamReference? jsStream = await Prompt("After you will press ok, long string will be generated");
if (jsStream != null) {
await using Stream referenceStream = await jsStream.OpenReadStreamAsync();
using var memStream = new MemoryStream();
await referenceStream.CopyToAsync(memStream);
var byteArray = memStream.ToArray();
str = System.Text.Encoding.Default.GetString(byteArray);
}
length = str?.Length ?? 0;
}
Or maybe even better, use an StreamReader
:或者甚至更好,使用
StreamReader
:
async void CallJS() {
string? str = null;
IJSStreamReference? jsStream = await Prompt("After you will press ok, long string will be generated");
if (jsStream != null) {
await using Stream referenceStream = await jsStream.OpenReadStreamAsync();
using var sr = new StreamReader(referenceStream);
var str = await sr.ReadToEndAsync();
}
length = str?.Length ?? 0;
}
If it still doesn't work, take a look at the maxAllowedSize
Parameter of the OpenReadStreamAsync
Method如果还是不行,看看
OpenReadStreamAsync
方法的maxAllowedSize
参数
I have managed to solve this problem only by chanking the message:我已经设法通过发送消息来解决这个问题:
TS: //Type Script Code: TS: //输入脚本代码:
let str = "";
//generate large string
export function exportImageAndGetBase64Length(message): number {
alert(message);
for(let i = 0; i < 164232; i++)
str += "A";
return str.length;
}
//get part of the generated string
export function getChunk(startIndex, endIndex): string {
return str.substring(startIndex, endIndex);
}
//finish transition and clean up the string
export function ClearBuffer() {
str = "";
}
Razor Razor
inject Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions> Options
C#: C#:
async void GetLongStringFromJS() {
int fileLength = await module.InvokeAsync<int>("exportImageAndGetBase64Length", "long string of 164232 will be generated and send to c#");
HubOptions a = Options.Value;
int maximumSingnalRMessageSize = (a.MaximumReceiveMessageSize == null || a.MaximumReceiveMessageSize > 32768) ? 32768 : (int)a.MaximumReceiveMessageSize;
int chunkLength = (int)maximumSingnalRMessageSize / sizeof(char);
StringBuilder sb = new StringBuilder();
for (int startIndex = 0, endIndex = chunkLength; startIndex <= fileLength; startIndex += chunkLength, endIndex += chunkLength) {
if (endIndex > fileLength + 1)
endIndex = fileLength + 1;
string chunk = await module.InvokeAsync<string>("getChunk", startIndex, endIndex);
sb.Append(chunk);
}
length = sb.Length; //do somthing with your string
await module.InvokeVoidAsync("ClearBuffer");
this.StateHasChanged();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.