如何从 Blazor WebAssembly 中的 sessionStorage 读取大字符串?我的结果被截断
How to read large string from sessionStorage in Blazor WebAssembly? My result is truncated
我正在开发一个新的 Blazor WebAssembly 应用程序 (NET 5.0),但我无法从会话存储中读取一个大字符串(约 3000 个字符)。我得到了一个结果,但它被截断了,中间添加了一个“...”。结果始终正好是 1000 字节。
在下面的代码中,dataKey是我要读取的数据的字符串键。 JSRuntime 注入如下:
@inject IJSRuntime JSRuntime
我第一次尝试从会话存储中读取项目是这样的:
// Initial try (truncated)
var myValue1 = await JSRuntime.InvokeAsync<string>("sessionStorage.getItem", dataKey);
后来搜了一下发现webassembly里面建议不要await,所以改成这样:
// Remove the await (still truncated)
var myValue2 = ((IJSInProcessRuntime)JSRuntime).Invoke<string>("sessionStorage.getItem", dataKey);
这给了我相同的结果,截断的字符串刚好为 1000 字节。
阅读更多内容后,我发现建议在某些情况下使用 Unmarshalled 调用。我试过了,但我的结果只是空的。我找不到此用例的明确示例,因此我的代码可能不正确。
// Unmarshalled (null)
var myValue3 = ((IJSUnmarshalledRuntime)JSRuntime).InvokeUnmarshalled<string, object>("sessionStorage.getItem", dataKey);
经过大量搜索,我找不到任何其他推荐。谁能帮我从会话存储中读取这个字符串?
谢谢!
我创建了一个页面,在该页面上初始化一个随机值被写入会话存储。单击按钮时,将读取该值并将其与预期值进行比较。结果显示出来,是真的。我在各种浏览器中测试过。
不过,这里有一种特殊的行为。如果您在 visual studio 中使用调试器(尚未在 vs 代码中测试但假设它们的行为相同),您将只会看到 1000 个字符,即使你的字符串有更多。在示例中,只需注释 <p>
标记即可看到,显示了 10,000 个字符,但调试器仅显示 1,000 个。
@page "/sessionStorage"
@inject IJSRuntime js
<h1>SessionStorage</h1>
@if (isSame.HasValue == true)
{
@*<p>@_expectedSessionValue</p>*@
<p>Result: @isSame</p>
}
<button class="btn btn-primary" @onclick="ReadSessionStorage">Click me</button>
@code {
private Boolean? isSame = null;
private String _expectedSessionValue = "";
private String _sessionKey = "key1";
protected async override Task OnInitializedAsync()
{
Random random = new Random(12345);
Char[] content = new char[10000];
for (int i = 0; i < content.Length; i++)
{
content[i] = (Char)('a' + random.Next(0, 26));
}
_expectedSessionValue = new string(content);
await js.InvokeVoidAsync("sessionStorage.setItem", new[] { _sessionKey, _expectedSessionValue });
base.OnInitialized();
}
protected async Task ReadSessionStorage()
{
await base.OnParametersSetAsync();
String value = await js.InvokeAsync<String>("sessionStorage.getItem", new[] { _sessionKey });
isSame = value == _expectedSessionValue;
StateHasChanged();
}
}
我正在开发一个新的 Blazor WebAssembly 应用程序 (NET 5.0),但我无法从会话存储中读取一个大字符串(约 3000 个字符)。我得到了一个结果,但它被截断了,中间添加了一个“...”。结果始终正好是 1000 字节。
在下面的代码中,dataKey是我要读取的数据的字符串键。 JSRuntime 注入如下:
@inject IJSRuntime JSRuntime
我第一次尝试从会话存储中读取项目是这样的:
// Initial try (truncated)
var myValue1 = await JSRuntime.InvokeAsync<string>("sessionStorage.getItem", dataKey);
后来搜了一下发现webassembly里面建议不要await,所以改成这样:
// Remove the await (still truncated)
var myValue2 = ((IJSInProcessRuntime)JSRuntime).Invoke<string>("sessionStorage.getItem", dataKey);
这给了我相同的结果,截断的字符串刚好为 1000 字节。
阅读更多内容后,我发现建议在某些情况下使用 Unmarshalled 调用。我试过了,但我的结果只是空的。我找不到此用例的明确示例,因此我的代码可能不正确。
// Unmarshalled (null)
var myValue3 = ((IJSUnmarshalledRuntime)JSRuntime).InvokeUnmarshalled<string, object>("sessionStorage.getItem", dataKey);
经过大量搜索,我找不到任何其他推荐。谁能帮我从会话存储中读取这个字符串?
谢谢!
我创建了一个页面,在该页面上初始化一个随机值被写入会话存储。单击按钮时,将读取该值并将其与预期值进行比较。结果显示出来,是真的。我在各种浏览器中测试过。
不过,这里有一种特殊的行为。如果您在 visual studio 中使用调试器(尚未在 vs 代码中测试但假设它们的行为相同),您将只会看到 1000 个字符,即使你的字符串有更多。在示例中,只需注释 <p>
标记即可看到,显示了 10,000 个字符,但调试器仅显示 1,000 个。
@page "/sessionStorage"
@inject IJSRuntime js
<h1>SessionStorage</h1>
@if (isSame.HasValue == true)
{
@*<p>@_expectedSessionValue</p>*@
<p>Result: @isSame</p>
}
<button class="btn btn-primary" @onclick="ReadSessionStorage">Click me</button>
@code {
private Boolean? isSame = null;
private String _expectedSessionValue = "";
private String _sessionKey = "key1";
protected async override Task OnInitializedAsync()
{
Random random = new Random(12345);
Char[] content = new char[10000];
for (int i = 0; i < content.Length; i++)
{
content[i] = (Char)('a' + random.Next(0, 26));
}
_expectedSessionValue = new string(content);
await js.InvokeVoidAsync("sessionStorage.setItem", new[] { _sessionKey, _expectedSessionValue });
base.OnInitialized();
}
protected async Task ReadSessionStorage()
{
await base.OnParametersSetAsync();
String value = await js.InvokeAsync<String>("sessionStorage.getItem", new[] { _sessionKey });
isSame = value == _expectedSessionValue;
StateHasChanged();
}
}