San*_*ain 7 c# asp.net-core blazor-server-side
我正在学习服务器端 blazor 并尝试学习身份验证。每当我使用 SignInManager.SignInAsync(.......) 时,它都会引发以下异常:
System.InvalidOperationException:无法修改响应标头,因为响应已开始。 在 Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.ThrowIfReadOnly() 在 Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.set_Item(String key, StringValues value) 在 Microsoft.AspNetCore.Http.ResponseCookies.Append(String key, String value, CookieOptions 选项) 位于 Microsoft.AspNetCore.Authentication.Cookies.ChunkingCookieManager.AppendResponseCookie(HttpContext context、String key、String value、CookieOptions options) 位于 Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleSignInAsync(ClaimsPrincipal 用户、AuthenticationProperties 属性) 位于 Microsoft。 AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext 上下文、字符串方案、ClaimsPrincipal 主体、AuthenticationProperties 属性) 位于 Microsoft.AspNetCore.Identity.SignInManager
1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable1 extraClaims),位于 C:\my_work\Blazor_learning\GroupMembersInfo 中的 GroupMembersInfo.Pages.RegisterUser.Register() \Pages\RegisterUser.razor:第 52 行位于 Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(任务任务)位于 Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync()
位于 Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(任务任务) )在 Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(任务 taskToHandle)
我认为异常是从我突出显示的方法中抛出的。那么我该如何缓解这个问题。这是我的代码
启动程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using GroupMembersInfo.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
namespace GroupMembersInfo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<AppDbContext>(
options => options.UseSqlServer(Configuration.GetConnectionString("GMIDbConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<AppDbContext>();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddSingleton<WeatherForecastService>();
services.ConfigureApplicationCookie(options =>
{
options.SlidingExpiration = true;
options.Events.OnRedirectToLogin = cxt =>
{
cxt.Response.StatusCode = 401;
return Task.CompletedTask;
};
options.Events.OnRedirectToAccessDenied = cxt =>
{
cxt.Response.StatusCode = 403;
return Task.CompletedTask;
};
options.Events.OnRedirectToLogout = cxt => Task.CompletedTask;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
登录组件代码
@page "/loginPage"
@using Microsoft.AspNetCore.Identity;
@using GroupMembersInfo.Data;
@inject UserManager<IdentityUser> UserManager
@inject SignInManager<IdentityUser> SignInManager
@inject NavigationManager NavigationManager
<h3>Log In</h3>
<div class="row">
<div class="col-md-12">
<EditForm Model="@RegisterUserModel" OnValidSubmit="@LogIn">
<div class="form-group">
<label>Iser Id: </label>
<input @bind-value="RegisterUserModel.Email" class="form-control" />
</div>
<div class="form-group">
<label>Password: </label>
<input @bind-value="RegisterUserModel.Password" class="form-control" />
</div>
<div class="form-group">
<button type="submit">Submit</button>
</div>
</EditForm>
</div>
</div>
@code {
public RegisterUserModel RegisterUserModel { get; set; } = new RegisterUserModel();
public async Task LogIn()
{
var user = new IdentityUser
{
UserName = RegisterUserModel.Email
};
user.PasswordHash = SignInManager.UserManager.PasswordHasher.HashPassword(user, RegisterUserModel.Password);
await SignInManager.SignInAsync(user, isPersistent: false);
NavigationManager.NavigateTo("/");
}
}
Run Code Online (Sandbox Code Playgroud)
问题出在下面两行:
await SignInManager.SignInAsync(user, isPersistent: false);
NavigationManager.NavigateTo("/");
Run Code Online (Sandbox Code Playgroud)
在 SignInAsync 完成之前,页面将导航到下一页。这就是 SignInAsync 无法完成其工作的原因。
解决方案:
如果您在 NavigationManager.NavigateTo 之前添加 return 语句,应该可以解决该问题。
这是因为在等待的操作完成之前该方法无法返回。
return NavigationManager.NavigateTo("/");
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
5175 次 |
| 最近记录: |