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:
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace CoreBB.Web.Controllers
{
public class ErrorController : Controller
{
public IActionResult Index()
{
var exception = HttpContext.Features.Get<IExceptionHandlerFeature>();
ViewData["StatusCode"] = HttpContext.Response.StatusCode;
ViewData["Message"] = exception.Error.Message;
ViewData["StackTrace"] = exception.Error.StackTrace;
return View();
}
public IActionResult AccessDenied()
{
return View();
}
}
}
然后分别添加 Index 和 AccessDenied 视图。
Index.cshtml:
@{
ViewBag.Title = "Error";
}
<h2>HTTP @ViewBag.StatusCode Error</h2>
<p>
<strong class="alert-warning">@ViewBag.Message</strong>
</p>
<hr />
<h5>Debug Information:</h5>
<p>
@ViewBag.StackTrace
</p>
AccessDenied.cshtml:
@{
ViewBag.Title = "Access Denied";
}
<h2>Access Denied</h2>
<p>
<strong class="alert-warning">You are not authorized to access this resource.</strong>
</p>
然后在 HomeController 的 Index 里手动抛出异常 throw new Exception("Fake Error");
测试错误处理的效果。
注入 dbContext
创建 UserController 后,先添加以下代码注入 dbContext:
public class UserController : Controller
{
private CoreBBContext _dbContext;
public UserController(CoreBBContext dbContext)
{
_dbContext = dbContext;
}
}
如你所见,这里没有使用 new 显式创建 CoreBBContext 实例。我们只是将构造函数中的 dbContext 参数赋给了它,那 dbContext 的值到底从何而来?
它来自于 ASP.NET Core 依赖注入系统。此处是所谓的构造器注入,即当构造函数被调用时,实例所需要的参数将被依赖注入容器自动创建。
注:需要依赖注入的参数的类型(此处的 CoreBBContext 类)必需提前在容器中进行注册。上一节的 service.AddDbContext<CoreBBContext>();
就是在进行注册。
asp-controller、asp-action、asp-for
直接附上 Register 视图的代码:
@model CoreBB.Web.Models.RegisterViewModel
@{
ViewBag.Title = "Register";
}
<div class="container col-4 offset-4" style="margin-top:120px">
<div class="card border-info">
<div class="card-header text-white bg-info">
<strong>Register</strong>
</div>
<div class="card-body">
<form asp-action="Register" method="post">
<div class="form-group">
<label asp-for="Name"></label>
<input class="form-control" asp-for="Name" />
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input class="form-control" asp-for="Password" type="password" />
</div>
<div class="form-group">
<label asp-for="RepeatPassword"></label>
<input class="form-control" asp-for="RepeatPassword" type="password" />
</div>
<div class="form-group">
<label asp-for="Description"></label>
<textarea class="form-control" style="min-height:120px" asp-for="Description"></textarea>
</div>
<input type="submit" class="btn btn-primary float-right" value="Register" />
</form>
</div>
</div>
</div>
asp-controller:用于显式指定控制器。此处未显式指定,意味着以当前控制器(UserController)为目标控制器
asp-action:
asp-for:将 HTML 标签特性与 Model 的属性绑定