ASP.NET Core MVC表单提交未触发控制器Http POST方法问题
ASP.NET Core MVC (.NET 8) 登录POST方法未触发问题
问题场景
正在学习ASP.NET Core MVC(.NET 8),构建示例项目时遇到以下问题:首页点击按钮能正常加载登录表单,但点击登录视图的「Log In」按钮时,控制器的[HttpPost] Login方法未被触发,只会调用GET版本的Login方法,无法完成登录流程。尝试将UserLogin从ViewModel改为Model,问题仍未解决。
相关代码如下:
1. Program.cs 服务注册
builder.Services.AddDbContext<ApplicationDbContext>(options=> options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); //registering the Authetication Services with COOKIE Autheticaition scheme builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(option => { option.LoginPath = "/UserAccess/Login"; option.ExpireTimeSpan = TimeSpan.FromMinutes(20); }); //some line of code then.. app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
2. 模型:UserLogin.cs
public class UserLogin { public string? Username { get; set; } public string? Password { get; set; } public bool KeepLoggedIn { get; set; } = false; }
3. 控制器:UserAccessController.cs
public class UserAccessController : Controller { public IActionResult Login() { return View(); } [HttpPost] public async Task<IActionResult> Login(UserLogin usrLogin) { //will perform password verification and generate Httpcontext return View(); } }
4. 视图:Login.cshtml
@model UserLogin <h1>User Entry according to Role</h1> <form method="post" asp-controller="UserAccess" asp-action="Login"> <div class="mt-2 mb-3"> <input asp-for="Username" type="text" class="form-control" placeholder="Username"> </div> <div> <input asp-for="Password" type="password" class="form-control" placeholder="Password"> </div> <div class="row mt-3"> <a class="col-3 ms-3 btn btn-outline-primary" role="button" >Log In</a> <a href="#" class="col-6 ms-2 text-decoration-none text-success">Forgot password?</a> </div> </form>
问题原因
问题出在登录视图的「Log In」按钮上:使用<a>标签作为提交按钮,但<a>标签默认发起GET请求,不会触发表单的POST提交。表单提交需要使用<button type="submit">或<input type="submit">元素。
修复方案
修改Login.cshtml中的登录按钮部分,将<a>标签替换为<button>标签:
<div class="row mt-3"> <button type="submit" class="col-3 ms-3 btn btn-outline-primary">Log In</button> <a href="#" class="col-6 ms-2 text-decoration-none text-success">Forgot password?</a> </div>
额外优化建议
- 添加CSRF令牌:ASP.NET Core MVC表单默认需要CSRF保护,使用
asp-controller和asp-action标签助手的表单会自动生成隐藏的CSRF令牌,若页面源码中无<input name="__RequestVerificationToken" type="hidden" value="...">,可手动添加@Html.AntiForgeryToken()到表单内。 - 补充KeepLoggedIn控件:模型中的
KeepLoggedIn字段未在视图中体现,可添加复选框:<div class="mt-2"> <input asp-for="KeepLoggedIn" type="checkbox"> <label asp-for="KeepLoggedIn">Keep me logged in</label> </div> - 添加表单验证:为模型添加数据注解,提升用户体验:
视图中添加验证提示:using System.ComponentModel.DataAnnotations; public class UserLogin { [Required(ErrorMessage = "Username is required")] public string? Username { get; set; } [Required(ErrorMessage = "Password is required")] public string? Password { get; set; } public bool KeepLoggedIn { get; set; } = false; }
控制器POST方法中检查模型状态:<div class="mt-2 mb-3"> <input asp-for="Username" type="text" class="form-control" placeholder="Username"> <span asp-validation-for="Username" class="text-danger"></span> </div> <div> <input asp-for="Password" type="password" class="form-control" placeholder="Password"> <span asp-validation-for="Password" class="text-danger"></span> </div>[HttpPost] public async Task<IActionResult> Login(UserLogin usrLogin) { if (!ModelState.IsValid) { return View(usrLogin); } // 执行密码验证和Cookie生成逻辑 return RedirectToAction("Index", "Home"); }
内容的提问来源于stack exchange,提问作者BaluS
相关产品推荐
相关产品推荐

