这是我几个星期以来一直遇到的问题。具体来说,这似乎发生在我在帐户控制器中的登录操作上。似乎也取决于我用来浏览站点的机器,因为我只在家用机器而不是工作机器上遇到问题。我知道它不是特定于浏览器的,因为两者都使用相同版本的Chrome。它也不是孤立在单个环境中的,因为我可以在本地进行调试并浏览网站本身。
起初,我认为这与我使用异步方法有关,因为我对同步方法的使用并不熟悉。我尝试剥离所有内容并使其完全同步,同时仍获得相同的结果。然后,我尝试将redirecttoaction / route / locals替换为仅返回视图,并且它起作用了。为了进一步确认这是罪魁祸首,我让登录表单遇到了一个完全不同的动作,除了简单的redirecttoaction(“ Index”,“ Home”)以外,它都是空的OTHER,并且该应用程序无限期地挂起。不幸的是,仅点击一个视图并不能满足我的需要,因为在很多情况下,我需要它来击打动作本身。
就其不一致而言,我能够一致地复制它的唯一方法是在本地运行该应用程序并登录。然后关闭浏览器并停止运行该应用程序。然后我再次运行该应用程序>注销>登录,它挂起。
我在stackoverflow和其他站点上进行了大量研究,并尝试了许多不同的建议,例如更改startup.cs中的配置设置,重新安装dll以及其他许多不计其数的事情,没有运气解决这个问题。
这里是构造函数,并且从帐户控制器登录get和post操作
private myContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
public AccountController(
myContext context,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
RoleManager<IdentityRole> roleManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_context = context;
_userManager = userManager;
_signInManager = signInManager;
_roleManager = roleManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<AccountController>();
}
// GET: /Account/Login
[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
ApplicationUser user = _userManager.Users.Where(a => a.Email == model.Email).FirstOrDefault();
if (user != null)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation(1, "User logged in.");
var RoleCustomer = _userManager.IsInRoleAsync(user, "Customer");
var RoleAdmin = _userManager.IsInRoleAsync(user, "Admin");
if (RoleCustomer.Result)
{
return RedirectToLocal(returnUrl);
}
else if (RoleAdmin.Result)
{
return RedirectToRoute(new { controller = "Home", action = "Admin" });
//return RedirectToLocal("/Home/Index");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
if (user.EmailConfirmed == false)
{
return View("ResendConfirm", new ResendConfirmViewModel() { user = user, returnUrl = returnUrl });
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
这是登录视图中的登录表单
<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
<h4>Use a local account to log in.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Password" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
<label asp-for="RememberMe">
<input asp-for="RememberMe" />
@Html.DisplayNameFor(m => m.RememberMe)
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Log in</button>
</div>
</div>
<p>
<a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">Register as a new user?</a>
</p>
<p>
<a asp-action="ForgotPassword">Forgot your password?</a>
</p>
</form>
这是启动类
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.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<myContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("WebApplication1ContextConnection")));
services.AddIdentityCore<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<myContext>()
.AddSignInManager()
.AddDefaultTokenProviders();
services.AddAuthentication(o =>
{
o.DefaultScheme = IdentityConstants.ApplicationScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies(o => { });
services.AddSession();
services.Configure<IdentityOptions>(options =>
{
// Default Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
options.SignIn.RequireConfirmedEmail = true;
options.SignIn.RequireConfirmedPhoneNumber = false;
options.User.AllowedUserNameCharacters ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = true;
});
services.ConfigureApplicationCookie(options =>
{
//should change this at some point to real access denied. something like Account/AccessDenied
options.AccessDeniedPath = "/Home/index";
options.Cookie.Name = "mycookie";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.LoginPath = "/Account/Login";
// ReturnUrlParameter requires
//using Microsoft.AspNetCore.Authentication.Cookies;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseSession();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
非常感谢您提供的任何帮助/指导。对此,我真的非常感激。如果有什么办法可以提供更多信息,请告诉我。