|
這里介紹了Razor基本用法
準(zhǔn)備工作
ConfigureServices添加Razor支持 public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); } 修改app.UseEndpoints為 app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
添加數(shù)據(jù)庫(kù) 1. 添加模型
[Table("Book")] public class Book { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Display(Name = "書(shū)名")] [Required(ErrorMessage = "書(shū)名不能為空")] [StringLength(50, ErrorMessage = "書(shū)名最大長(zhǎng)度為50")] public string Name { get; set; } [Display(Name = "單價(jià)")] [Column(TypeName = "decimal(18, 2)")] [Range(0.01, 10000, ErrorMessage = "單價(jià)范圍只能在(0.01 ~ 10000)"), DataType(DataType.Currency)] public decimal UnitPrice { get; set; } [Display(Name = "出版日期")] [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")] public DateTime PublicationDate { get; set; } [Display(Name = "創(chuàng)建時(shí)間")] [DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")] public DateTime CreateTime { get; set; } [Display(Name = "最后更新時(shí)間")] [DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")] public DateTime? LastUpdateTime { get; set; } } 2. 添加DbContext
public class RazorDbContext : DbContext { public RazorDbContext(DbContextOptions<RazorDbContext> options) : base(options) { } public DbSet<Razor.Models.Book> Book { get; set; } } 3. 安裝dotnet-ef(全局安裝),終端輸入 dotnet tool install --global dotnet-ef
4. 添加遷移
dotnet ef migrations add InitialDb 5. 更新到數(shù)據(jù)庫(kù) dotnet ef database update InitialDb 6. 添加種子數(shù)據(jù)
public static class SeedData { public static void Initialize(IServiceProvider serviceProvider) { var options = serviceProvider.GetRequiredService<DbContextOptions<RazorDbContext>>(); using (var context = new RazorDbContext(options)) { if (context.Book.Any()) { return; } context.Book.AddRange( new Models.Book { Name = "算法之美", UnitPrice = 26.99m, PublicationDate = DateTime.Parse("2016-08-20"), CreateTime = DateTime.Now }, new Models.Book { Name = "大話設(shè)計(jì)模式", UnitPrice = 28.03m, PublicationDate = DateTime.Parse("2015-06-12"), CreateTime = DateTime.Now }, new Models.Book { Name = "幸福的陷阱", UnitPrice = 30.59m, PublicationDate = DateTime.Parse("2018-09-13"), CreateTime = DateTime.Now }, new Models.Book { Name = "墨菲定律", UnitPrice = 32.12m, PublicationDate = DateTime.Parse("2018-09-13"), CreateTime = DateTime.Now } ); context.SaveChanges(); } } }
經(jīng)過(guò)上面的步驟就可以在程序中使用數(shù)據(jù)庫(kù)
Razor頁(yè)面 一、路由
@page指令
二、讀取數(shù)據(jù)(以上面模型為例) 1. 創(chuàng)建Index頁(yè)面 dotnet new page -o=Pages -na="Razor.Pages" -n="Index" 2. PageModel 的OnGet讀取數(shù)據(jù)
public class IndexModel : PageModel { private readonly Data.RazorDbContext _dbContext; public IndexModel(Data.RazorDbContext dbContext) { _dbContext = dbContext; } public List<Models.Book> Books { get; set; } public IActionResult OnGet() { if (_dbContext == null) { return NotFound(); } Books = _dbContext.Book .AsNoTracking() .ToList(); return Page(); } } 3. 頁(yè)面展示數(shù)據(jù)
@page @model IndexModel @{ ViewData["Title"] = "圖書(shū)管理"; } <table class="table table-bordered text-center"> <thead> <tr> <th> @Html.DisplayNameFor(model => model.Books[0].Name) </th> <th> @Html.DisplayNameFor(model => model.Books[0].UnitPrice) </th> <th> @Html.DisplayNameFor(model => model.Books[0].PublicationDate) </th> <th> @Html.DisplayNameFor(model => model.Books[0].CreateTime) </th> <th > @Html.DisplayNameFor(model => model.Books[0].LastUpdateTime) </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model.Books) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.UnitPrice) </td> <td> @Html.DisplayFor(modelItem => item.PublicationDate) </td> <td> @Html.DisplayFor(modelItem => item.CreateTime) </td> <td> @Html.DisplayFor(modelItem => item.LastUpdateTime) </td> <td> <a asp-page="./Edit" asp-route-id="@item.Id">編輯</a> | <a asp-page="./Delete" asp-route-id="@item.Id">刪除</a> </td> </tr> } </tbody> </table>
三、更新數(shù)據(jù) 1. 創(chuàng)建Edit頁(yè)面 dotnet new page -o=Pages -na="Razor.Pages" -n="Edit" 2. PageModel拉去數(shù)據(jù)
public IActionResult OnGet(int? id) { if (id == null) { return NotFound(); } Book = _dbContext.Book .AsNoTracking() .FirstOrDefault(m => m.Id == id); if(Book == null) { return NotFound(); } return Page(); } 3. 編輯Edit頁(yè)面
@page "{id:int}" @model Razor.Pages.EditModel @{ ViewData["Title"] = "編輯書(shū)本"; } <div class="row"> <div class="col-md-4"> <form method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input type="hidden" asp-for="Book.Id" /> <div class="form-group"> <label asp-for="Book.Name" class="control-label"></label> <input asp-for="Book.Name" class="form-control" /> <span asp-validation-for="Book.Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Book.UnitPrice" class="control-label"></label> <input asp-for="Book.UnitPrice" class="form-control" /> <span asp-validation-for="Book.UnitPrice" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Book.PublicationDate" class="control-label"></label> <input asp-for="Book.PublicationDate" class="form-control" /> <span asp-validation-for="Book.PublicationDate" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="保存" class="btn btn-primary" /> </div> </form> </div> </div> 4. OnPost處理請(qǐng)求
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
var model = _dbContext.Book.FirstOrDefault(m => m.Id == Book.Id);
if (model == null)
{
return NotFound();
}
model.Name = Book.Name;
model.PublicationDate = Book.PublicationDate;
model.UnitPrice = Book.UnitPrice;
_dbContext.SaveChanges();
return RedirectToPage("Index");
}
用asp-for生成的輸入框,會(huì)加上客戶端驗(yàn)證,查看原代碼可以發(fā)現(xiàn) <input class="form-control" type="text" data-val="true" data-val-length="书名最大长度为50" data-val-length-max="50" data-val-required="书名不能为空" id="Book_Name" maxlength="50" name="Book.Name" value="大话设计模式" /> 它是根據(jù)模型定義的驗(yàn)證,生成屬性,然后用jquery-validation驗(yàn)證,這樣我們沒(méi)有寫(xiě)一行前端代碼就能達(dá)到客戶端驗(yàn)證效果,微軟真的把DRY做到極致。當(dāng)然后端的驗(yàn)證也是不能漏的
篩選器 Razor 頁(yè)面篩選器提供的以下方法可在全局或頁(yè)面級(jí)應(yīng)用:
異步方法:
一、全局篩選器
1. 創(chuàng)建GlobalPageFilter類,實(shí)現(xiàn)IPageFilter接口
public class GlobalPageFilter : IPageFilter { private readonly ILogger _logger; public GlobalPageFilter(ILogger logger) { _logger = logger; } public void OnPageHandlerExecuted(PageHandlerExecutedContext context) { _logger.LogDebug("Global Filter OnPageHandlerSelected called."); } public void OnPageHandlerExecuting(PageHandlerExecutingContext context) { _logger.LogDebug("Global Filter OnPageHandlerExecuting called."); } public void OnPageHandlerSelected(PageHandlerSelectedContext context) { _logger.LogDebug("Global Filter OnPageHandlerSelected called."); } } 2. 創(chuàng)建過(guò)濾器工廠類,實(shí)現(xiàn)IFilterFactory接口
public class GlobalPagerFilterWithFactory : IFilterFactory { public bool IsReusable => false; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { var logger = serviceProvider.GetService<ILogger<Filters.GlobalPageFilter>>(); return new Filters.GlobalPageFilter(logger); } } 3. ConfigureServices添加RazorPage選項(xiàng) services.AddRazorPages() .AddRazorPagesOptions(options => { options.Conventions.ConfigureFilter(new Factories.GlobalPagerFilterWithFactory()); });
二、特定PageModel篩選器 在PageModel里面重載
public override void OnPageHandlerSelected(Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext context) { _logger.LogDebug("OnPageHandlerSelected"); } //在執(zhí)行處理器方法前,模型綁定完成后調(diào)用 public override void OnPageHandlerExecuting(Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext context) { _logger.LogDebug("OnPageHandlerExecuting"); } //在執(zhí)行處理器方法后,生成操作結(jié)果前調(diào)用 public override void OnPageHandlerExecuted(Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext context) { _logger.LogDebug("OnPageHandlerExecuted"); }
示例代碼:https://github.com/WilsonPan/AspNetCoreExamples/tree/master/Razor |
|
|