Razor Pages
Razor Pages 是基于页面的 ASP.NET Core Web App 架构。
相比 MVC 模式,Razor Pages的生产效率更快。
Razer Pages 需要两个中间件:
- builder…Services.AddRazorPages 添加 Razor Pages services
- app.MapRazorPages 添加 Razor Pages endpoints
.cshtml 与 .cshtml.cs
在最简单的页面中:
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
看起来与 MVC 的页面差不多,但特别之处是有一个 @page 指令,@page 指令意味着这个页面可以直接接收 http request,而不需要通过 controller。
第2个页面Pages/Index2.cshtml 的代码是这样的:
@page
@using RazorPagesIntro.Pages
@model Index2Model<h2>Separate page model</h2>
<p>@Model.Message
</p>
使用了 @using RazorPagesIntro.Pages 指令,
而RazorPagesIntro.Pages的实现代码Pages/Index2.cshtml.cs是这样的:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;namespace RazorPagesIntro.Pages
{public class Index2Model : PageModel{public string Message { get; private set; } = "PageModel in C#";public void OnGet(){Message += $" Server time is { DateTime.Now }";}}
}
一个Index2.cshtml 页面,搭配一个Index2.cshtml.cs,类似WPF 中的 xaml与 xaml.cs。
URL Path 路由
url 的 Path 与页面的 path 相匹配。比如:
- / or /Index 匹配 /Pages/Index.cshtml
- /Contact 匹配 /Pages/Contact.cshtml
- /Store/Contact 匹配 /Pages/Store/Contact.cshtml
一个 Post 例子
有一个Pages/Customers/Create.cshtml 的 view 页面,代码如下:
@model 指令中的CreateModel 对应一个名为 Create 的 Model,
而 Form 的 submit 会发生 Http Post,
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<p>Enter a customer name:</p><form method="post">Name:<input asp-for="Customer!.Name" /><input type="submit" />
</form>
相应的Pages/Customers/Create.cshtml.cs 的代码中的部分如下:
OnPostAsync 处理 cshtml 中的 form submit,
一般还会有一个OnGet方法处理Http Get 请求。
RedirectToPage 方法会重定向到 ./Index 路径。
[BindProperty] 注解属性是表示model binding。
Razor Pages 中的BindProperty 一般用于非 GET 的属性。
[BindProperty]
public Customer? Customer { get; set; }public async Task<IActionResult> OnPostAsync()
{if (!ModelState.IsValid){return Page();}if (Customer != null) _context.Customer.Add(Customer);return RedirectToPage("./Index");
}
Home Page 的例子
Index.cshtml
@page
@model RazorPagesContacts.Pages.Customers.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<h1>Contacts home page</h1>
<form method="post"><table class="table"><thead><tr><th>ID</th><th>Name</th><th></th></tr></thead><tbody>@if (Model.Customers != null){foreach (var contact in Model.Customers){<tr><td> @contact.Id </td><td>@contact.Name</td><td><!-- <snippet_Edit> --><a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |<!-- </snippet_Edit> --><!-- <snippet_Delete> --><button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button><!-- </snippet_Delete> --></td></tr>}}</tbody></table><a asp-page="Create">Create New</a>
</form>
其中的
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
使用asp-route-id 生成指向Edit页面的URL,URL 中包含 Contact id,比如:
https://localhost:5001/Edit/1
而delete方法的html
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
由 server 生成后的html是:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
对应的 Model 的代码Index.cshtml.cs:
public class IndexModel : PageModel
{private readonly Data.CustomerDbContext _context;public IndexModel(Data.CustomerDbContext context){_context = context;}public IList<Customer>? Customers { get; set; }public async Task OnGetAsync(){Customers = await _context.Customer.ToListAsync();}public async Task<IActionResult> OnPostDeleteAsync(int id){var contact = await _context.Customer.FindAsync(id);if (contact != null){_context.Customer.Remove(contact);await _context.SaveChangesAsync();}return RedirectToPage();}
}
使用Layouts,Partial,模板和Tag Helpers
待更新
URL Generation
待更新
ViewData 属性
待更新
TempData 属性
待更新