Tag Helper

Tag Helper 比 HTML helper 的可读性更强,看起来就像直接编写 HTML 标签。

常用的 Tag Helper 有以下四种:

  • asp-action:指定 MVC action

  • asp-controller:指定 MVC controller

  • asp-route-xxx:指定路由参数

  • asp-for:将 Model 属性绑定到 HTML 标签特性

创建错误处理控制器

其实之前 Startup.cs 里面的代码已经启用了错误处理的相关功能。

app.UseExceptionHandler(“/Error/Index”);
使用 ErrorController 的 Index 方法去处理内容异常,并显示错误消息。

option.AccessDeniedPath= “/Error/AccessDenied”;
使用 ErrorController 的 AccessDenied 方法去提示用户没有访问权限。

现在在 Controller 文件夹添加真正的 ErrorController:

  1. using Microsoft.AspNetCore.Diagnostics;
  2. using Microsoft.AspNetCore.Mvc;
  3. namespace CoreBB.Web.Controllers
  4. {
  5. public class ErrorController : Controller
  6. {
  7. public IActionResult Index()
  8. {
  9. var exception = HttpContext.Features.Get<IExceptionHandlerFeature>();
  10. ViewData["StatusCode"] = HttpContext.Response.StatusCode;
  11. ViewData["Message"] = exception.Error.Message;
  12. ViewData["StackTrace"] = exception.Error.StackTrace;
  13. return View();
  14. }
  15. public IActionResult AccessDenied()
  16. {
  17. return View();
  18. }
  19. }
  20. }

然后分别添加 Index 和 AccessDenied 视图。

Index.cshtml:

  1. @{
  2. ViewBag.Title = "Error";
  3. }
  4. <h2>HTTP @ViewBag.StatusCode Error</h2>
  5. <p>
  6. <strong class="alert-warning">@ViewBag.Message</strong>
  7. </p>
  8. <hr />
  9. <h5>Debug Information:</h5>
  10. <p>
  11. @ViewBag.StackTrace
  12. </p>

AccessDenied.cshtml:

  1. @{
  2. ViewBag.Title = "Access Denied";
  3. }
  4. <h2>Access Denied</h2>
  5. <p>
  6. <strong class="alert-warning">You are not authorized to access this resource.</strong>
  7. </p>

然后在 HomeController 的 Index 里手动抛出异常 throw new Exception("Fake Error"); 测试错误处理的效果。

3 用户管理 - 图1

注入 dbContext

创建 UserController 后,先添加以下代码注入 dbContext:

  1. public class UserController : Controller
  2. {
  3. private CoreBBContext _dbContext;
  4. public UserController(CoreBBContext dbContext)
  5. {
  6. _dbContext = dbContext;
  7. }
  8. }

如你所见,这里没有使用 new 显式创建 CoreBBContext 实例。我们只是将构造函数中的 dbContext 参数赋给了它,那 dbContext 的值到底从何而来?
它来自于 ASP.NET Core 依赖注入系统。此处是所谓的构造器注入,即当构造函数被调用时,实例所需要的参数将被依赖注入容器自动创建。

注:需要依赖注入的参数的类型(此处的 CoreBBContext 类)必需提前在容器中进行注册。上一节的 service.AddDbContext<CoreBBContext>(); 就是在进行注册。

asp-controller、asp-action、asp-for

直接附上 Register 视图的代码:

  1. @model CoreBB.Web.Models.RegisterViewModel
  2. @{
  3. ViewBag.Title = "Register";
  4. }
  5. <div class="container col-4 offset-4" style="margin-top:120px">
  6. <div class="card border-info">
  7. <div class="card-header text-white bg-info">
  8. <strong>Register</strong>
  9. </div>
  10. <div class="card-body">
  11. <form asp-action="Register" method="post">
  12. <div class="form-group">
  13. <label asp-for="Name"></label>
  14. <input class="form-control" asp-for="Name" />
  15. </div>
  16. <div class="form-group">
  17. <label asp-for="Password"></label>
  18. <input class="form-control" asp-for="Password" type="password" />
  19. </div>
  20. <div class="form-group">
  21. <label asp-for="RepeatPassword"></label>
  22. <input class="form-control" asp-for="RepeatPassword" type="password" />
  23. </div>
  24. <div class="form-group">
  25. <label asp-for="Description"></label>
  26. <textarea class="form-control" style="min-height:120px" asp-for="Description"></textarea>
  27. </div>
  28. <input type="submit" class="btn btn-primary float-right" value="Register" />
  29. </form>
  30. </div>
  31. </div>
  32. </div>
  • asp-controller:用于显式指定控制器。此处未显式指定,意味着以当前控制器(UserController)为目标控制器

  • asp-action:

    中的 asp-action 显式指明了 form 的目标 action

  • asp-for:将 HTML 标签特性与 Model 的属性绑定

Lab_Files 3.zip