C# 如何访问Blazor中的浏览器localStorage?
我想支持JWTs,所以我需要保留令牌;有什么设施可以访问这个吗?或者我们现在应该注册自己的javascript函数来访问这个功能吗 编辑:根据建议,我尝试将JS interop用作:C# 如何访问Blazor中的浏览器localStorage?,c#,asp.net-core,blazor,C#,Asp.net Core,Blazor,我想支持JWTs,所以我需要保留令牌;有什么设施可以访问这个吗?或者我们现在应该注册自己的javascript函数来访问这个功能吗 编辑:根据建议,我尝试将JS interop用作: <script> localStorage.setItem("key1", "key1data"); Blazor.registerFunction("readStorage", (key) => { return localStorage.getItem(key)
<script>
localStorage.setItem("key1", "key1data");
Blazor.registerFunction("readStorage", (key) => {
return localStorage.getItem(key);
});
</script>
@if (jwtKey == null)
{
<div class="login-panel">
<p>JWT not loaded</p>
</div>
}
else
{
<div class="login-panel">
<p>@jwtKey</p>
</div>
}
@functions {
public RenderFragment Body { get; set; }
string jwtKey;
protected override async Task OnInitAsync()
{
jwtKey = RegisteredFunction.Invoke<string>("readStorage", "key1");
if (jwtKey == null)
{
jwtKey = "Unknown";
}
}
}
setItem(“key1”、“key1data”);
Blazor.registerFunction(“readStorage”,(键)=>{
返回localStorage.getItem(键);
});
@if(jwtKey==null)
{
JWT未加载
}
其他的
{
@jwtKey
}
@功能{
公共RenderFragment主体{get;set;}
字符串jwtKey;
受保护的重写异步任务OnInitAsync()
{
jwtKey=RegisteredFunction.Invoke(“readStorage”、“key1”);
if(jwtKey==null)
{
jwtKey=“未知”;
}
}
}
但这会导致diag中出现WASM错误:
WASM:
[Microsoft.AspNetCore.Blazor.Browser.Interop.JavaScriptException]
找不到名为“readStorage”的注册函数。WASM:
错误:找不到名为“readStorage”的注册函数
仅供参考,这在Blazor VS样板项目的MainLayout.cshtml中
(如果合适,可以提出一个新问题;不过与此问题有些关联)对于0.1,您需要编写自己的javascript互操作。但我相信这是一个成功的东西,也许在0.2版本中 或者(如果会话之间不需要存储),您可以编写自己的DI单例,如下所示: 编辑
有一个公开的公关,所以确实应该很快: Edit2
0.2已完成,但还没有本地存储。同时,我已经为此开发了一个包:同样在nuget上,默认情况下,它可能会在Blazor中实现,但目前我正在使用:
如果其他人对此感到困惑(截至2018年7月6日): Steve Sanderson在他的NDC会议视频中谈到了这个问题(本地存储): 从大约45分钟开始 他使用一个nuget软件包来实现:
页面上有使用示例,因此无需在此处重新绘制。现在有一个名为Blazor.Extensions.Storage的包,它是一个精心策划的扩展
微软有自己的软件包,但到目前为止,该软件包尚未投入生产且仅适用于服务器端blazor 如果您不想拥有第三方依赖,可以通过
jsinterop
轻松实现
public class LocalStorage
{
private readonly IJSRuntime _jsRuntime;
public LocalStorage(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public async Task SetAsync<T>(string key, T value)
{
string jsVal = null;
if (value != null)
jsVal = JsonSerializer.Serialize(value);
await _jsRuntime.InvokeVoidAsync("localStorage.setItem",
new object[] { key, jsVal });
}
public async Task<T> GetAsync<T>(string key)
{
string val = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
if (val == null) return default;
T result = JsonSerializer.Deserialize<T>(val);
return result;
}
public async Task RemoveAsync(string key)
{
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
}
public async Task ClearAsync()
{
await _jsRuntime.InvokeVoidAsync("localStorage.clear");
}
}
公共类本地存储
{
私有只读IJSRuntime\jsu运行时;
公共本地存储(IJSRuntime jsRuntime)
{
_jsRuntime=jsRuntime;
}
公共异步任务SetAsync(字符串键,T值)
{
字符串jsVal=null;
if(值!=null)
jsVal=JsonSerializer.Serialize(值);
wait_jsRuntime.InvokeVoidAsync(“localStorage.setItem”,
新对象[]{key,jsVal});
}
公共异步任务GetAsync(字符串键)
{
string val=await_jsRuntime.InvokeAsync(“localStorage.getItem”,key);
如果(val==null)返回默认值;
T result=JsonSerializer.Deserialize(val);
返回结果;
}
公共异步任务RemoveAsync(字符串键)
{
wait_jsRuntime.InvokeVoidAsync(“localStorage.removietem”,key);
}
公共异步任务ClearAsync()
{
wait_jsRuntime.InvokeVoidAsync(“localStorage.clear”);
}
}
用法:
await _localStorage.SetAsync("Test", 42);
var val = await _localStorage.GetAsync<int>("Test");
await _localStorage.RemoveAsync("Test");
await _localStorage.ClearAsync();
wait_localStorage.SetAsync(“Test”,42);
var val=await_localStorage.GetAsync(“测试”);
wait_localStorage.RemoveAsync(“测试”);
wait_localStorage.clearsync();
太棒了,谢谢:)我试着按照你的建议使用现有的互操作,但它似乎不起作用?(更新问题以说明)啊,是的,这解决了它。似乎应该有一种方法来序列化这种情况下的操作(即,如果用户登录,他们会得到一个面板而不是另一个)。如果blazor团队缺少工作项:)我要做的是在路由器标记下方的app.cshtml中注册我的javascript函数,你应该试试。不会改变我系统上的行为(仍然抛出);这似乎是在时间问题上的一个补丁,使javascript更有可能首先执行,但如果不能保证它会执行,则是危险的。实际上,最干净的解决方案显然是
,而(true){try{Invoke()}catch(JavaScriptException){wait Task.Delay(100);}}}
(/sarcasm)我用一个按钮作为触发器进行了测试,效果良好。我猜脚本是在异步调用之后执行的。因此,您应该在进程的早期注册函数。它不适用于最新版本--.net core 3 preview 5