Here introduces the basic usage Razor
- Razor create a page with PageModel
- Use Database
- Display data
- update data
- Filters
Ready to work
- Initializing an empty items (input terminal: dotnet new web -n = Razor)
- Nuget add Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.Design
- Add the necessary services
ConfigureServices add support for Razor
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); }
To modify app.UseEndpoints
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
Add Database
[Table("Book")] public class Book { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Display (the Name = " title " )] [The Required (the ErrorMessage = " title can not be blank " )] [The StringLength ( 50 , the ErrorMessage = " title maximum length of 50 " )] public String the Name { GET ; SET ;} [Display (the Name = " monovalent " )] [Column(TypeName = "decimal(18, 2)")] [The Range ( 0.01 , 10000 , the ErrorMessage = " monovalent range only (0.01 ~ 10000) " ), the DataType (DataType.Currency)] public decimal the UnitPrice { GET ; SET ;} [Display (the Name = " publication date " )] [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")] public DateTime PublicationDate { get; set; } [Display (the Name = " Created " )] [DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")] public DateTime CreateTime { get; set; } [Display (the Name = " last updated " )] [DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")] public DateTime? LastUpdateTime { get; set; } }
2. Add DbContext
public class RazorDbContext : DbContext { public RazorDbContext(DbContextOptions<RazorDbContext> options) : base(options) { } public DbSet<Razor.Models.Book> Book { get; set; } }
3. Installation dotnet-ef (global installed), the input terminal
dotnet tool install --global dotnet-ef
dotnet ef migrations add InitialDb
5. Update the database
dotnet ef database update InitialDb
6. Add seed data
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 { The Name = " beauty Algorithms " , UnitPrice = 26.99m, PublicationDate = DateTime.Parse("2016-08-20"), CreateTime = DateTime.Now }, new Models.Book { The Name = " Westward design mode " , UnitPrice = 28.03m, PublicationDate = DateTime.Parse("2015-06-12"), CreateTime = DateTime.Now }, new Models.Book { The Name = " happiness trap " , UnitPrice = 30.59m, PublicationDate = DateTime.Parse("2018-09-13"), CreateTime = DateTime.Now }, new Models.Book { The Name = " Murphy's Law " , UnitPrice = 32.12m, PublicationDate = DateTime.Parse("2018-09-13"), CreateTime = DateTime.Now } ); context.SaveChanges(); } } }
After the above step may be used in the program database
Razor page
- Razor must be the first instruction on the page
- By default, Url folder hierarchy generated in accordance with the route can also be specified later @page
- Parameters can be bound, for example: {id: int}
Second, the read data (as an example in the above model)
1. Create Index page
dotnet new page -o=Pages -na="Razor.Pages" -n="Index"
2. PageModel the read data OnGet
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. Data page display
@page @model Index Model @{ ViewData [ " the Title " ] = " library management " ; } <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>
Third, update data
1. Create Edit Page
dotnet new page -o=Pages -na="Razor.Pages" -n="Edit"
2. PageModel got me data
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 Edit Page
@page "{id:int}" @model Razor.Pages.EditModel @{ ViewData [ "Title"] = "Edit book"; } <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 processing request
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 with the generated input box, will add the client authentication, the original code can be found in view
<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="大话设计模式" />
It is based on the verification model definition, build properties, and then verify with jquery-validation, so we did not write a single line of code to achieve front-end client to verify the effect, Microsoft really put DRY achieve the ultimate. Of course, the back-end verification is not leaking
Filters
The following method Razor page filter can be provided in a global or page-level applications:
Synchronization method:
- OnPageHandlerSelected: but the call before the model binding takes place after selection handler method.
- OnPageHandlerExecuting: Before performing processor method, model binding after the call is completed.
- OnPageHandlerExecuted: after method executed by a processor, generates an operation result of the previous call.
Asynchronous methods:
- OnPageHandlerSelectionAsync: After selecting the handler method, but before the model binding occurs, asynchronous calls.
- OnPageHandlerExecutionAsync: Before calling the handler method, but at the end of the model binding, to make asynchronous calls.
public class GlobalPageFilter: IPageFilter { private readonly ILogger _logger; public GlobalPageFilter(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<GlobalPageFilter>(); } 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. ConfigureServices Add Filter
services.AddMvc(options => { options.Filters.Add<Filters.GlobalPageFilter>(); });
public override void OnPageHandlerSelected(Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext context) { _logger.LogDebug("OnPageHandlerSelected"); } // Before executing processor method, after the completion of call model binding public the override void OnPageHandlerExecuting (Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext context) { _logger.LogDebug("OnPageHandlerExecuting"); } // After the method executed by a processor, generates an operation result of the call before the public the override void OnPageHandlerExecuted (Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext context) { _logger.LogDebug("OnPageHandlerExecuted"); }
Sample Code: https://github.com/WilsonPan/AspNetCoreExamples/tree/master/Razor