jwt - Blazored.LocalStorage.ILocalStorageService.GetItemAsync (字符串))
问题描述
我是 .NET6 的新手,我在 .NET 6 中创建了 blazor WASM 应用程序。它的身份验证部分是 JWT 身份验证。当我要将令牌存储到本地存储中时,会发生以下错误。
blazor.webassembly.js:1 System.AggregateException:发生一个或多个错误。(找不到方法:System.Threading.Tasks.ValueTask 1<!!0> Blazored.LocalStorage.ILocalStorageService.GetItemAsync<!0>(string)) ---> System.MissingMethodException: Method not found: System.Threading.Tasks.ValueTask
1<!!0>
Blazored.LocalStorage.ILocalStorageService.GetItemAsync<!0>(string) at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[d__8](d__8& stateMachine) in System.Private.CoreLib.dll:token 0x600454a+0x28 at Infrastructure.Manager.Preferences .ClientPreferenceManager.GetPreference() in Infrastructure.dll:token 0x600004d+0xc at BlSls.Client.Program.Main(String[] args) in BlSls\Client\Program.cs:line 36 --- 内部异常堆栈跟踪结束 - --
我的程序.cs
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args).AddRootComponents().AddClientServices();
var host = builder.Build();
var storageService = host.Services.GetRequiredService<ClientPreferenceManager>();
if (storageService != null)
{
CultureInfo culture;
var preference = await storageService.GetPreference() as ClientPreference;
}
builder.Services.AddMudServices();
builder.Services.AddTransient<ILocalItemStore,LocalItemStore>();
builder.Services.AddSingleton<IDataConnect, DataConnect>();
builder.Services.AddScoped<Service.InterData>();
await builder.Build().RunAsync();
}
ILocalStorageService.cs
public interface ILocalStorageService
{
event EventHandler<ChangingEventArgs> Changing;
event EventHandler<ChangedEventArgs> Changed;
ValueTask ClearAsync();
ValueTask<bool> ContainKeyAsync(string key);
ValueTask<string> GetItemAsStringAsync(string key);
ValueTask<T> GetItemAsync<T>(string key);
ValueTask<string> KeyAsync(int index);
ValueTask<int> LengthAsync();
ValueTask RemoveItemAsync(string key);
ValueTask SetItemAsync<T>(string key, T data);
}
import.razor 中所需的 DI
@inject BL10StateProvider _stateProvider
@inject IAuthenticationManager _authenticationManager
登录.razor
<div class="d-block">
<EditForm Model="@_tokenModel" OnValidSubmit="SubmitAsync">
<DataAnnotationsValidator />
<div class="@(f ? "invalid-box":"user-box")">
<InputText placeholder="Username" @bind-Value="_tokenModel.UserName" />
<ValidationMessage For="() => _tokenModel.UserName" />
@*<label class="body-default">Email</label>*@
</div>
<div class="@(f ? "invalid-box":"user-box")">
<InputText type="password" placeholder="Password" @bind-Value="_tokenModel.Password" />
<ValidationMessage For="() => _tokenModel.Password" />
@*<label class="body-default">Password</label>*@
</div>
<div>
<button type="submit" class="btn-block login-btn button-text"> Sign In</button>
</div>
</EditForm>
</div>
登录.razor.cs
public partial class Login
{
bool f = false;
private TokenRequest _tokenModel = new();
protected override async Task OnInitializedAsync()
{
var state = await _stateProvider.GetAuthenticationStateAsync();
if (state != new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())))
{
_navigationManager.NavigateTo("/login");
}
await Task.FromResult(0);
}
private async Task SubmitAsync()
{
var result = await _authenticationManager.Login(_tokenModel);
if (result.Succeeded)
{
f = false;
_navigationManager.NavigateTo("/CompanySelection", true);
}
else
{
_tokenModel.Messaage = "UserName Or Password Incorrect";
f = true;
}
}
}
BL10StateProvider.cs
public class BL10StateProvider {
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var savedToken = await _localStorage.GetItemAsync<string>(StorageConstants.Local.AuthToken);
if (string.IsNullOrWhiteSpace(savedToken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", savedToken);
var state = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(GetClaimsFromJwt(savedToken), "jwt")));
AuthenticationStateUser = state.User;
return state;
}
}
身份验证管理器.cs
public class AuthenticationManager{
public async Task<IResult> Login(TokenRequest model)
{
HttpResponseMessage response=null;
try
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), TokenEndpoints.Authenticate))
{
request.Headers.TryAddWithoutValidation("Timestamp", DateTime.Now.Ticks.ToString());
request.Content = JsonContent.Create(model);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
response = await httpClient.SendAsync(request);
}
}
}
catch (Exception exp)
{
model.Messaage = "Login Falied";
model.IsTokenRequestFailed = true;
return await Result.FailAsync("Server Or API Host Not found");
}
//HttpRequestMessage req = new HttpRequestMessage();
//req.Method = HttpMethod.Post;
//req.RequestUri = TokenEndpoints.Authenticate;
//req.
////var response = await _httpClient.PostAsJsonAsync(TokenEndpoints.Authenticate, model);
// var response = await _httpClient.PostAsJsonAsync()
string responseBody = await response.Content.ReadAsStringAsync();
TokenResponse tokenRequest = JsonConvert.DeserializeObject<TokenResponse>(responseBody);
//var result = await response.ToResult<TokenResponse>();
if (tokenRequest.IsSuccess)
{
model.IsTokenRequestFailed = false;
model.Messaage = "Login Successful";
var token = tokenRequest.Token;
var refreshToken = tokenRequest.RefreshToken;
var userImageURL = tokenRequest.UserImageURL;
await _localStorage.SetItemAsync(StorageConstants.Local.AuthToken, token);
await _localStorage.SetItemAsync(StorageConstants.Local.RefreshToken, refreshToken);
if (!string.IsNullOrEmpty(userImageURL))
{
await _localStorage.SetItemAsync(StorageConstants.Local.UserImageURL, userImageURL);
}
((BL10StateProvider)this._authenticationStateProvider).MarkUserAsAuthenticated(model.UserName);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return await Result.SuccessAsync();
}
else
{
model.Messaage = "Login Falied";
model.IsTokenRequestFailed = true ;
return await Result.FailAsync(tokenRequest.Messages);
}
}
}
请使用上面的代码示例帮助我解决这个问题。
解决方案
当您在 Main() 中时,在 .RunAsync() 之前,JavaScript 尚未加载。
错误在这一行:
var preference = await storageService.GetPreference() as ClientPreference;
无论您对此有什么逻辑,都必须稍后执行。
一个可能的位置是在 App 组件中,在 OnAfterRenderAsync(true) 中:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var preference = await storageService.GetPreference() as ClientPreference;
...
}
}
但请注意,在您设置该首选项之前,您的第一页可能已经在初始化和渲染。
推荐阅读
- python - 从 node.js 调用 python 函数
- java - 通过服务器将数据传递给客户端
- python - 如何使用 sudo 运行 jupyterhub。错误:找不到命令
- javascript - React - 传递道具,导航器中的设置错误?
- jquery - 单击后禁用按钮或立即关闭模式
- javascript - 使用简单数组中的 javascript 创建动态 html 表
- java - spring boot 无法启动嵌入式tomcat
- c# - 如何在 C# 中使用 SAP B1 屏幕画家表单字段
- python-3.x - 没有名为 ncdump 的模块
- c - 如何初始化只有空格而没有垃圾的字符串?