如何在.cshtml控制器中处理错误,不跳转错误页而在原视图显示提示?
实现登录失败时在原视图显示错误消息
你提到的在ViewModel中新增属性存储错误信息的方法完全可行,不过更推荐使用ASP.NET Core内置的ModelState机制——它和框架的表单验证体系深度集成,代码更规范。下面分别给出两种实现方案:
方案一:使用ModelState(推荐)
不需要修改ViewModel,直接利用框架的错误状态管理:
1. 修改AuthController的SignIn方法
去掉抛出异常的逻辑,改为向ModelState添加错误信息,然后返回登录视图:
public class AuthController : Controller { private readonly UserManager<IdentityUser> _userManager; // 假设你用的是Identity框架 public AuthController(UserManager<IdentityUser> userManager) { _userManager = userManager; } [Route("signin")] [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> SignIn(SignInViewModel model) { ViewData["ReturnUrl"] = model.ReturnUrl; if (ModelState.IsValid) { // 根据用户名查询用户(补充你原代码缺失的步骤) var user = await _userManager.FindByNameAsync(model.Username); if (user == null || !await _userManager.CheckPasswordAsync(user, model.Password)) { // 向ModelState添加全局错误信息 ModelState.AddModelError(string.Empty, "用户名或密码错误"); // 返回登录视图,保留用户输入的表单数据 return View(model); } // 登录成功后的逻辑(比如创建Cookie、跳转ReturnUrl) // ... } // 模型验证失败时也返回原视图 return View(model); } }
2. 修改SignIn.cshtml视图
在表单内添加条件渲染的错误提示:
@model AuthServer.ViewModels.SignInViewModel <form autocomplete="off" asp-route="SignIn"> <input type="hidden" asp-for="ReturnUrl"/> <div class="card"> <!-- 显示全局验证错误 --> <div asp-validation-summary="ModelOnly" class="text-danger mb-2"></div> <input type="text" class="form-control" asp-for="Username" autofocus> <span asp-validation-for="Username" class="text-danger d-block mt-1"></span> <input type="password" class="form-control mt-2" asp-for="Password"> <span asp-validation-for="Password" class="text-danger d-block mt-1"></span> </div> <p class="mt-3"> <button type="submit">Sign in</button> </p> </form>
asp-validation-summary会自动渲染ModelState中的错误信息,无需手动拼接。
方案二:在ViewModel中添加错误属性
如果你更倾向于用自定义属性管理错误,按以下步骤实现:
1. 更新SignInViewModel
新增存储错误信息的属性:
public class SignInViewModel { [Required] public string Username { get; set; } [Required] public string Password { get; set; } public string? ReturnUrl { get; set; } // 新增错误信息属性 public string? ErrorMessage { get; set; } }
2. 修改AuthController逻辑
登录失败时为ErrorMessage赋值,返回原视图:
public async Task<IActionResult> SignIn(SignInViewModel model) { ViewData["ReturnUrl"] = model.ReturnUrl; if (ModelState.IsValid) { var user = await _userManager.FindByNameAsync(model.Username); if (user == null || !await _userManager.CheckPasswordAsync(user, model.Password)) { model.ErrorMessage = "用户名或密码错误"; return View(model); } // 登录成功逻辑 // ... } return View(model); }
3. 修改视图显示错误
在表单中添加条件判断:
@model AuthServer.ViewModels.SignInViewModel <form autocomplete="off" asp-route="SignIn"> <input type="hidden" asp-for="ReturnUrl"/> <div class="card"> <input type="text" class="form-control" asp-for="Username" autofocus> <input type="password" class="form-control mt-2" asp-for="Password"> </div> <p class="mt-3"> <button type="submit">Sign in</button> </p> <!-- 条件显示自定义错误信息 --> @if (!string.IsNullOrEmpty(Model.ErrorMessage)) { <div class="alert alert-danger mt-3">@Model.ErrorMessage</div> } </form>
两种方案都能实现你要的效果,推荐优先用ModelState,因为它能统一处理模型验证错误和业务逻辑错误,更符合ASP.NET Core的设计规范。
内容的提问来源于stack exchange,提问作者char m
相关产品推荐
相关产品推荐

