【转】asp.net Core 系列【一】——创建Web应用
ASP.NET Core 中的 Razor 頁(yè)面介紹
Razor 頁(yè)面是 ASP.NET Core MVC 的一個(gè)新功能,它可以使基于頁(yè)面的編碼方式更簡(jiǎn)單高效。
若要查找使用模型視圖控制器方法的教程,請(qǐng)參閱?ASP.NET Core MVC 入門(mén)。
?
ASP.NET Core 2.0 必備組件
安裝?.NET Core?2.0.0 或更高版本。
如果在使用 Visual Studio,請(qǐng)使用以下工作負(fù)載安裝?Visual Studio?2017 版本 15.3 或更高版本:
- ASP.NET 和 Web 開(kāi)發(fā)
- .NET Core 跨平臺(tái)開(kāi)發(fā)
?
創(chuàng)建 Razor 頁(yè)面項(xiàng)目
- Visual Studio ?
- Visual Studio for Mac ?
- Visual Studio Code ?
- .NET Core CLI
請(qǐng)參閱?Razor 頁(yè)面入門(mén),獲取關(guān)于如何使用 Visual Studio 創(chuàng)建 Razor 頁(yè)面項(xiàng)目的詳細(xì)說(shuō)明。
Razor 頁(yè)面
Startup.cs 中已啟用 Razor 頁(yè)面:
public class Startup {public void ConfigureServices(IServiceCollection services){// Includes support for Razor Pages and controllers. services.AddMvc();}public void Configure(IApplicationBuilder app){app.UseMvc();} }?
請(qǐng)考慮一個(gè)基本頁(yè)面:
@page<h1>Hello, world!</h1> <h2>The time on the server is @DateTime.Now</h2>?
上述代碼看上去類(lèi)似于一個(gè) Razor 視圖文件。 不同之處在于?@page?指令。?@page?使文件轉(zhuǎn)換為一個(gè) MVC 操作 ,這意味著它將直接處理請(qǐng)求,而無(wú)需通過(guò)控制器處理。?@page?必須是頁(yè)面上的第一個(gè) Razor 指令。?@page?將影響其他 Razor 構(gòu)造的行為。
將在以下兩個(gè)文件中顯示使用?PageModel?類(lèi)的類(lèi)似頁(yè)面。 Pages/Index2.cshtml 文件:
@page @using RazorPages @model IndexModel2<h2>Separate page model</h2> <p>@Model.Message </p>?
Pages/Index2.cshtml.cs“代碼隱藏”文件:
using Microsoft.AspNetCore.Mvc.RazorPages; using System;namespace RazorPages {public class IndexModel2 : PageModel{public string Message { get; private set; } = "PageModel in C#";public void OnGet(){Message += $" Server time is { DateTime.Now }";}} }?
按照慣例,PageModel?類(lèi)文件的名稱(chēng)與追加 .cs 的 Razor 頁(yè)面文件名稱(chēng)相同。 例如,前面的 Razor 頁(yè)面的名稱(chēng)為 Pages/Index2.cshtml。 包含?PageModel?類(lèi)的文件的名稱(chēng)為 Pages/Index2.cshtml.cs。
頁(yè)面的 URL 路徑的關(guān)聯(lián)由頁(yè)面在文件系統(tǒng)中的位置決定。 下表顯示了 Razor 頁(yè)面路徑及匹配的 URL:
| /Pages/Index.cshtml | /?或?/Index |
| /Pages/Contact.cshtml | /Contact |
| /Pages/Store/Contact.cshtml | /Store/Contact |
| /Pages/Store/Index.cshtml | /Store?或?/Store/Index |
注意:
- 默認(rèn)情況下,運(yùn)行時(shí)在“頁(yè)面”文件夾中查找 Razor 頁(yè)面文件。
- URL 未包含頁(yè)面時(shí),Index?為默認(rèn)頁(yè)面。
編寫(xiě)基本窗體
Razor 頁(yè)面功能旨在簡(jiǎn)化 Web 瀏覽器常用的模式。?模型綁定、標(biāo)記幫助程序和 HTML 幫助程序均只可用于 Razor 頁(yè)面類(lèi)中定義的屬性。 請(qǐng)參考為?Contact?模型實(shí)現(xiàn)基本的“聯(lián)系我們”窗體的頁(yè)面:
在本文檔中的示例中,DbContext?在?Startup.cs?文件中進(jìn)行初始化。
C#復(fù)制 using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using RazorPagesContacts.Data; namespace RazorPagesContacts { public class Startup { public IHostingEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { services.AddDbContext<AppDbContext>(options => options.UseInMemoryDatabase("name")); services.AddMvc(); } public void Configure(IApplicationBuilder app) { app.UseMvc(); } } }數(shù)據(jù)模型:
C#復(fù)制 using System.ComponentModel.DataAnnotations;namespace RazorPagesContacts.Data {public class Customer { public int Id { get; set; } [數(shù)據(jù)庫(kù)上下文:
C#復(fù)制 using Microsoft.EntityFrameworkCore;namespace RazorPagesContacts.Data {public class AppDbContext : DbContext { public AppDbContext(DbContextOptions options) : base(options) { } public DbSet<Customer> Customers { get; set; } } }Pages/Create.cshtml 視圖文件:
cshtml復(fù)制 @page @model RazorPagesContacts.Pages.CreateModel @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<html> <body><p>Enter your name.</p><div asp-validation-summary="All"></div><form method="POST"> <div>Name: <input asp-for="Customer.Name" /></div> <input type="submit" /> </form> </body> </html>Pages/Create.cshtml.cs 代碼隱藏視圖文件:
C#復(fù)制 using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using RazorPagesContacts.Data;namespace RazorPagesContacts.Pages { public class CreateModel : PageModel { private readonly AppDbContext _db; public CreateModel(AppDbContext db) { _db = db; } [按照慣例,PageModel?類(lèi)稱(chēng)為?<PageName>Model并且它與頁(yè)面位于同一個(gè)命名空間中。
使用?PageModel?代碼隱藏文件支持單元測(cè)試,但是需要你編寫(xiě)顯式構(gòu)造函數(shù)和類(lèi)。 未使用?PageModel?代碼隱藏文件的頁(yè)面支持運(yùn)行時(shí)編譯,這在開(kāi)發(fā)過(guò)程中可以作為一種優(yōu)勢(shì)。
頁(yè)面包含?OnPostAsync?處理程序方法,它在?POST?請(qǐng)求上運(yùn)行(當(dāng)用戶(hù)發(fā)布窗體時(shí))。 可以為任何 HTTP 謂詞添加處理程序方法。 最常見(jiàn)的處理程序是:
- OnGet,用于初始化頁(yè)面所需的狀態(tài)。?OnGet?示例。
- OnPost,用于處理窗體提交。
Async?命名后綴為可選,但是按照慣例通常會(huì)將它用于異步函數(shù)。 前面示例中的?OnPostAsync?代碼看上去與通常在控制器中編寫(xiě)的內(nèi)容相似。 前面的代碼通常用于 Razor 頁(yè)面。 多數(shù) MVC 基元(例如模型綁定、驗(yàn)證和操作結(jié)果)都是共享的。
之前的?OnPostAsync?方法:
C#復(fù)制 public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _db.Customers.Add(Customer); await _db.SaveChangesAsync(); return RedirectToPage("/Index"); }OnPostAsync?的基本流:
檢查驗(yàn)證錯(cuò)誤。
- 如果沒(méi)有錯(cuò)誤,則保存數(shù)據(jù)并重定向。
- 如果有錯(cuò)誤,則再次顯示頁(yè)面并附帶驗(yàn)證消息。 客戶(hù)端驗(yàn)證與傳統(tǒng)的 ASP.NET Core MVC 應(yīng)用程序相同。 很多情況下,都會(huì)在客戶(hù)端上檢測(cè)到驗(yàn)證錯(cuò)誤,并且從不將它們提交到服務(wù)器。
成功輸入數(shù)據(jù)后,OnPostAsync?處理程序方法調(diào)用?RedirectToPage?幫助程序方法來(lái)返回?RedirectToPageResult?的實(shí)例。?RedirectToPage?是新的操作結(jié)果,類(lèi)似于?RedirectToAction?或?RedirectToRoute,但是已針對(duì)頁(yè)面進(jìn)行自定義。 在前面的示例中,它將重定向到根索引頁(yè) (/Index)。?頁(yè)面 URL 生成部分中詳細(xì)介紹了?RedirectToPage。
提交的窗體存在(已傳遞到服務(wù)器的)驗(yàn)證錯(cuò)誤時(shí),OnPostAsync?處理程序方法調(diào)用?Page?幫助程序方法。?Page?返回?PageResult?的實(shí)例。 返回?Page?的過(guò)程與控制器中的操作返回?View?的過(guò)程相似。?PageResult?是處理程序方法的默認(rèn)?返回類(lèi)型。 返回?void?的處理程序方法將顯示頁(yè)面。
Customer?屬性使用?[BindProperty]?特性來(lái)選擇加入模型綁定。
C#復(fù)制 public class CreateModel : PageModel {private readonly AppDbContext _db; public CreateModel(AppDbContext db) { _db = db; } [默認(rèn)情況下,Razor 頁(yè)面只綁定帶有非 GET 謂詞的屬性。 綁定屬性可以減少需要編寫(xiě)的代碼量。 綁定通過(guò)使用相同的屬性顯示窗體字段 (<input asp-for="Customer.Name" />) 來(lái)減少代碼,并接受輸入。
主頁(yè) (Index.cshtml):
cshtml復(fù)制 @page @model RazorPagesContacts.Pages.IndexModel @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<h1>Contacts</h1> <form method="post"> <table class="table"> <thead> <tr> <th>ID</th> <th>Name</th> </tr> </thead> <tbody> @foreach (var contact in Model.Customers) { <tr> <td>@contact.Id</td> <td>@contact.Name</td> <td> <a asp-page="./Edit" asp-route-id="@contact.Id">edit</a> <button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button> </td> </tr> } </tbody> </table> <a asp-page="./Create">Create</a> </form>Index.cshtml.cs 隱藏文件:
C#復(fù)制 using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using RazorPagesContacts.Data; using System.Collections.Generic; using Microsoft.EntityFrameworkCore; namespace RazorPagesContacts.Pages { public class IndexModel : PageModel { private readonly AppDbContext _db; public IndexModel(AppDbContext db) { _db = db; } public IList<Customer> Customers { get; private set; } public async Task OnGetAsync() { Customers = await _db.Customers.AsNoTracking().ToListAsync(); } public async Task<IActionResult> OnPostDeleteAsync(int id) { var contact = await _db.Customers.FindAsync(id); if (contact != null) { _db.Customers.Remove(contact); await _db.SaveChangesAsync(); } return RedirectToPage(); } } }Index.cshtml 文件包含以下標(biāo)記來(lái)創(chuàng)建每個(gè)聯(lián)系人項(xiàng)的編輯鏈接:
cshtml復(fù)制 <a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>定位點(diǎn)標(biāo)記幫助程序?使用?asp-route-{value}?屬性生成“編輯”頁(yè)面的鏈接。 此鏈接包含路由數(shù)據(jù)及聯(lián)系人 ID。 例如?http://localhost:5000/Edit/1。
Pages/Edit.cshtml 文件:
cshtml復(fù)制 @page "{id:int}" @model RazorPagesContacts.Pages.EditModel @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers@{ViewData["Title"] = "Edit Customer"; }<h1>Edit Customer - @Model.Customer.Id</h1> <form method="post"> <div asp-validation-summary="All"></div> <input asp-for="Customer.Id" type="hidden" /> <div> <label asp-for="Customer.Name"></label> <div> <input asp-for="Customer.Name" /> <span asp-validation-for="Customer.Name" ></span> </div> </div> <div> <button type="submit">Save</button> </div> </form>第一行包含?@page "{id:int}"?指令。 路由約束?"{id:int}"?告訴頁(yè)面接受包含?int?路由數(shù)據(jù)的頁(yè)面請(qǐng)求。 如果頁(yè)面請(qǐng)求未包含可轉(zhuǎn)換為?int的路由數(shù)據(jù),則運(yùn)行時(shí)返回 HTTP 404(未找到)錯(cuò)誤。
Pages/Edit.cshtml.cs 文件:
C#復(fù)制 using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using RazorPagesContacts.Data; namespace RazorPagesContacts.Pages { public class EditModel : PageModel { private readonly AppDbContext _db; public EditModel(AppDbContext db) { _db = db; } [Index.cshtml 文件還包含用于為每個(gè)客戶(hù)聯(lián)系人創(chuàng)建刪除按鈕的標(biāo)記:
cshtml復(fù)制 <button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>刪除按鈕采用 HTML 呈現(xiàn),其?formaction?包括參數(shù):
- asp-route-id?屬性指定的客戶(hù)聯(lián)系人 ID。
- asp-page-handler?屬性指定的?handler。
下面是呈現(xiàn)的刪除按鈕的示例,其中客戶(hù)聯(lián)系人 ID 為?1:
html復(fù)制 <button type="submit" formaction="/?id=1&handler=delete">delete</button>選中按鈕時(shí),向服務(wù)器發(fā)送窗體?POST?請(qǐng)求。 按照慣例,根據(jù)方案?OnPost[handler]Async?基于?handler?參數(shù)的值來(lái)選擇處理程序方法的名稱(chēng)。
因?yàn)楸臼纠?handler?是?delete,因此?OnPostDeleteAsync?處理程序方法用于處理?POST?請(qǐng)求。 如果?asp-page-handler?設(shè)置為不同值(如?remove),則選擇名稱(chēng)為?OnPostRemoveAsync?的頁(yè)面處理程序方法。
C#復(fù)制 public async Task<IActionResult> OnPostDeleteAsync(int id) { var contact = await _db.Customers.FindAsync(id); if (contact != null) { _db.Customers.Remove(contact); await _db.SaveChangesAsync(); } return RedirectToPage(); }OnPostDeleteAsync?方法:
- 接受來(lái)自查詢(xún)字符串的?id。
- 使用?FindAsync?查詢(xún)客戶(hù)聯(lián)系人的數(shù)據(jù)庫(kù)。
- 如果找到客戶(hù)聯(lián)系人,則從客戶(hù)聯(lián)系人列表將其刪除。 數(shù)據(jù)庫(kù)將更新。
- 調(diào)用?RedirectToPage,重定向到根索引頁(yè) (/Index)。
XSRF/CSRF 和 Razor 頁(yè)面
無(wú)需為防偽驗(yàn)證編寫(xiě)任何代碼。 Razor 頁(yè)面自動(dòng)將防偽標(biāo)記生成過(guò)程和驗(yàn)證過(guò)程包含在內(nèi)。
將布局、分區(qū)、模板和標(biāo)記幫助程序用于 Razor 頁(yè)面
頁(yè)面可使用 Razor 視圖引擎的所有功能。 布局、分區(qū)、模板、標(biāo)記幫助程序、_ViewStart.cshtml 和 _ViewImports.cshtml 的工作方式與它們?cè)趥鹘y(tǒng)的 Razor 視圖中的工作方式相同。
我們來(lái)使用其中的一些功能來(lái)整理此頁(yè)面。
向 Pages/_Layout.cshtml 添加布局頁(yè)面:
cshtml復(fù)制布局:
- 控制每個(gè)頁(yè)面的布局(頁(yè)面選擇退出布局時(shí)除外)。
- 導(dǎo)入 HTML 結(jié)構(gòu),例如 JavaScript 和樣式表。
請(qǐng)參閱布局頁(yè)面了解詳細(xì)信息。
在 Pages/_ViewStart.cshtml 中設(shè)置?Layout?屬性:
cshtml復(fù)制注意:布局位于“頁(yè)面”文件夾中。 頁(yè)面按層次結(jié)構(gòu)從當(dāng)前頁(yè)面的文件夾開(kāi)始查找其他視圖(布局、模板、分區(qū))。 可以從“頁(yè)面”文件夾下的任意 Razor 頁(yè)面使用“頁(yè)面”文件夾中的布局。
建議不要將布局文件放在“視圖/共享”文件夾中。 視圖/共享 是一種 MVC 視圖模式。 Razor 頁(yè)面旨在依賴(lài)文件夾層次結(jié)構(gòu),而非路徑約定。
Razor 頁(yè)面中的視圖搜索包含“頁(yè)面”文件夾。 用于 MVC 控制器和傳統(tǒng) Razor 視圖的布局、模板和分區(qū)可直接工作。
添加 Pages/_ViewImports.cshtml 文件:
cshtml復(fù)制 @namespace RazorPagesContacts.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers本教程的后續(xù)部分中將介紹?@namespace。?@addTagHelper?指令將內(nèi)置標(biāo)記幫助程序引入“頁(yè)面”文件夾中的所有頁(yè)面。
頁(yè)面上顯式使用?@namespace?指令后:
cshtml復(fù)制 @page @namespace RazorPagesIntro.Pages.Customers@model NameSpaceModel<h2>Name space</h2> <p>@Model.Message </p>此指令將為頁(yè)面設(shè)置命名空間。?@model?指令無(wú)需包含命名空間。
_ViewImports.cshtml 中包含?@namespace?指令后,指定的命名空間將為在導(dǎo)入?@namespace?指令的頁(yè)面中生成的命名空間提供前綴。 生成的命名空間的剩余部分(后綴部分)是包含 _ViewImports.cshtml 的文件夾與包含頁(yè)面的文件夾之間以點(diǎn)分隔的相對(duì)路徑。
例如,代碼隱藏文件 Pages/Customers/Edit.cshtml.cs 顯式設(shè)置命名空間:
C#復(fù)制 namespace RazorPagesContacts.Pages {public class EditModel : PageModel { private readonly AppDbContext _db; public EditModel(AppDbContext db) { _db = db; } // Code removed for brevity.Pages/_ViewImports.cshtml 文件設(shè)置以下命名空間:
cshtml復(fù)制 @namespace RazorPagesContacts.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers為 Pages/Customers/Edit.cshtml Razor 頁(yè)面生成的命名空間與代碼隱藏文件相同. 已對(duì)?@namespace?指令進(jìn)行設(shè)計(jì),因此添加到項(xiàng)目的 C# 類(lèi)和頁(yè)面生成的代碼可直接工作,而無(wú)需添加代碼隱藏文件的?@using?指令。
注意:@namespace?也可用于傳統(tǒng)的 Razor 視圖。
原始的 Pages/Create.cshtml 視圖文件:
cshtml復(fù)制 @page @model RazorPagesContacts.Pages.CreateModel @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<html> <body><p>Enter your name.</p><div asp-validation-summary="All"></div> <form method="POST"> <div>Name: <input asp-for="Customer.Name" /></div> <input type="submit" /> </form> </body> </html>更新后的 Pages/Create.cshtml 視圖文件:
cshtml復(fù)制 @page @model CreateModel<html> <body> <p> Enter your name. </p> <div asp-validation-summary="All"></div> <form method="POST"> <div>Name: <input asp-for="Customer.Name" /></div> <input type="submit" /> </form> </body> </html>Razor 頁(yè)面初學(xué)者項(xiàng)目包含 Pages/_ValidationScriptsPartial.cshtml,它與客戶(hù)端驗(yàn)證聯(lián)合。
頁(yè)面的 URL 生成
之前顯示的?Create?頁(yè)面使用?RedirectToPage:
C#復(fù)制 public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _db.Customers.Add(Customer); await _db.SaveChangesAsync(); return RedirectToPage("/Index"); }應(yīng)用具有以下文件/文件夾結(jié)構(gòu):
-
/Pages
- Index.cshtml
-
/Customer
- Create.cshtml
- Edit.cshtml
- Index.cshtml
成功后,Pages/Customers/Create.cshtml 和 Pages/Customers/Edit.cshtml 頁(yè)面將重定向到 Pages/Index.cshtml。 字符串?/Index?是用于訪問(wèn)上一頁(yè)的 URI 的組成部分。 可以使用字符串?/Index?生成 Pages/Index.cshtml 頁(yè)面的 URI。 例如:
- Url.Page("/Index", ...)
- <a asp-page="/Index">My Index Page</a>
- RedirectToPage("/Index")
頁(yè)面名稱(chēng)是從根“/Pages”文件夾到頁(yè)面的路徑(包含前導(dǎo)?/,例如?/Index)。 相較于僅對(duì) URL 硬編碼,前面的 URL 生成示例的功能更加強(qiáng)大。 URL 生成使用路由,并且可以根據(jù)目標(biāo)路徑定義路由的方式生成參數(shù)并對(duì)參數(shù)編碼。
頁(yè)面的 URL 生成支持相對(duì)名稱(chēng)。 下表顯示了 Pages/Customers/Create.cshtml 中不同的?RedirectToPage?參數(shù)選擇的索引頁(yè):
| RedirectToPage("/Index") | Pages/Index |
| RedirectToPage("./Index"); | Pages/Customers/Index |
| RedirectToPage("../Index") | Pages/Index |
| RedirectToPage("Index") | Pages/Customers/Index |
RedirectToPage("Index")、RedirectToPage("./Index")?和?RedirectToPage("../Index")?是相對(duì)名稱(chēng)。 結(jié)合?RedirectToPage?參數(shù)與當(dāng)前頁(yè)的路徑來(lái)計(jì)算目標(biāo)頁(yè)面的名稱(chēng)。
構(gòu)建結(jié)構(gòu)復(fù)雜的站點(diǎn)時(shí),相對(duì)名稱(chēng)鏈接很有用。 如果使用相對(duì)名稱(chēng)鏈接文件夾中的頁(yè)面,則可以重命名該文件夾。 所有鏈接仍然有效(因?yàn)檫@些鏈接未包含此文件夾名稱(chēng))。
TempData
ASP.NET 在控制器上公開(kāi)了?TempData?屬性。 此屬性可存儲(chǔ)數(shù)據(jù),直至數(shù)據(jù)被讀取。?Keep?和?Peek?方法可用于檢查數(shù)據(jù),而不執(zhí)行刪除。 多個(gè)請(qǐng)求需要數(shù)據(jù)時(shí),TempData?有助于進(jìn)行重定向。
[TempData]?是 ASP.NET Core 2.0 中的新屬性,在控制器和頁(yè)面上受支持。
下面的代碼使用?TempData?設(shè)置?Message?的值:
C#復(fù)制 public class CreateDotModel : PageModel {private readonly AppDbContext _db; public CreateDotModel(AppDbContext db) { _db = db; } [Pages/Customers/Index.cshtml 文件中的以下標(biāo)記使用?TempData?顯示?Message?的值。
cshtml復(fù)制 <h3>Msg: @Model.Message</h3>Pages/Customers/Index.cshtml.cs 代碼隱藏文件將?[TempData]?屬性應(yīng)用到?Message?屬性。
C#復(fù)制 [請(qǐng)參閱?TempData?了解詳細(xì)信息。
針對(duì)一個(gè)頁(yè)面的多個(gè)處理程序
以下頁(yè)面使用?asp-page-handler?標(biāo)記幫助程序?yàn)閮蓚€(gè)頁(yè)面處理程序生成標(biāo)記:
cshtml復(fù)制 @page @model CreateFATHModel<html> <body><p> Enter your name. </p> <div asp-validation-summary="All"></div> <form method="POST"> <div>Name: <input asp-for="Customer.Name" /></div> <input type="submit" asp-page-handler="JoinList" value="Join" /> <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" /> </form> </body> </html>前面示例中的窗體包含兩個(gè)提交按鈕,每個(gè)提交按鈕均使用?FormActionTagHelper?提交到不同的 URL。?asp-page-handler?是?asp-page?的配套屬性。?asp-page-handler?生成提交到頁(yè)面定義的各個(gè)處理程序方法的 URL。 未指定?asp-page,因?yàn)槭纠焰溄拥疆?dāng)前頁(yè)面。
代碼隱藏文件:
C#復(fù)制 using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using RazorPagesContacts.Data;namespace RazorPagesContacts.Pages.Customers { public class CreateFATHModel : PageModel { private readonly AppDbContext _db; public CreateFATHModel(AppDbContext db) { _db = db; } [前面的代碼使用已命名處理程序方法。 已命名處理程序方法通過(guò)采用名稱(chēng)中?On<HTTP Verb>?之后及?Async?之前的文本(如果有)創(chuàng)建。 在前面的示例中,頁(yè)面方法是 OnPostJoinListAsync 和 OnPostJoinListUCAsync。 刪除 OnPost 和 Async 后,處理程序名稱(chēng)為?JoinList?和?JoinListUC。
cshtml復(fù)制 <input type="submit" asp-page-handler="JoinList" value="Join" /> <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />使用前面的代碼時(shí),提交到?OnPostJoinListAsync?的 URL 路徑為?http://localhost:5000/Customers/CreateFATH?handler=JoinList。 提交到?OnPostJoinListUCAsync?的 URL 路徑為?http://localhost:5000/Customers/CreateFATH?handler=JoinListUC。
自定義路由
如果你不喜歡 URL 中的查詢(xún)字符串??handler=JoinList,可以更改路由,將處理程序名稱(chēng)放在 URL 的路徑部分。 可以通過(guò)在?@page?指令后面添加使用雙引號(hào)括起來(lái)的路由模板來(lái)自定義路由。
cshtml復(fù)制 @page "{handler?}" @model CreateRouteModel<html> <body> <p> Enter your name. </p> <div asp-validation-summary="All"></div> <form method="POST"> <div>Name: <input asp-for="Customer.Name" /></div> <input type="submit" asp-page-handler="JoinList" value="Join" /> <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" /> </form> </body> </html>前面的路由將處理程序放在了 URL 路徑中,而不是查詢(xún)字符串中。?handler?前面的???表示路由參數(shù)為可選。
可以使用?@page?將其他段和參數(shù)添加到頁(yè)面的路由中。 其中的任何內(nèi)容均會(huì)被追加到頁(yè)面的默認(rèn)路由中。 不支持使用絕對(duì)路徑或虛擬路徑更改頁(yè)面的路由(例如?"~/Some/Other/Path")。
配置和設(shè)置
若要配置高級(jí)選項(xiàng),請(qǐng)?jiān)?MVC 生成器上使用?AddRazorPagesOptions?擴(kuò)展方法:
C#復(fù)制 public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddRazorPagesOptions(options => { options.RootDirectory = "/MyPages"; options.Conventions.AuthorizeFolder("/MyPages/Admin"); }); }目前,可以使用?RazorPagesOptions?設(shè)置頁(yè)面的根目錄,或者為頁(yè)面添加應(yīng)用程序模型約定。 我們希望將來(lái)可以通過(guò)這種方式實(shí)現(xiàn)更多擴(kuò)展功能。
轉(zhuǎn)載于:https://www.cnblogs.com/dayang12525/p/7693208.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的【转】asp.net Core 系列【一】——创建Web应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: zufeoj 分数线划定
- 下一篇: 轻量级ORM框架 【Dapper】 的使