RazorASP.NET Core 中的頁面簡介Introduction to Razor Pages in ASP.NET Core
作者:Rick Anderson 與 Ryan NowakBy Rick Anderson and Ryan Nowak
Razor 頁面可讓撰寫以頁面為焦點的案常式序代碼比使用控制器和視圖更簡單且更具生產力。Razor Pages can make coding page-focused scenarios easier and more productive than using controllers and views.
如果您在尋找使用模型檢視控制器方法的教學課程,請參閱開始使用 ASP.NET Core MVC。If you're looking for a tutorial that uses the Model-View-Controller approach, see Get started with ASP.NET Core MVC.
本檔提供 Razor 頁面簡介。This document provides an introduction to Razor Pages. 它不是逐步教學課程。It's not a step by step tutorial. 如果您發現某些區段太過先進,請參閱 開始使用 Razor 頁面。If you find some of the sections too advanced, see Get started with Razor Pages. 如需 ASP.NET Core 的概觀,請參閱ASP.NET Core 簡介。For an overview of ASP.NET Core, see the Introduction to ASP.NET Core.
必要條件Prerequisites
- Visual StudioVisual Studio
- Visual Studio CodeVisual Studio Code
- Visual Studio for MacVisual Studio for Mac
使用 ASP.NET 和 網頁程式開發 工作負載 Visual Studio 2019 16.4 或更新版本Visual Studio 2019 16.4 or later with the ASP.NET and web development workload
- Visual StudioVisual Studio
- Visual Studio CodeVisual Studio Code
- Visual Studio for MacVisual Studio for Mac
- 使用 ASP.NET 和 網頁程式開發 工作負載 Visual Studio 2019 16.8 或更新版本Visual Studio 2019 16.8 or later with the ASP.NET and web development workload
- .NET 5.0 SDK 或更新版本.NET 5.0 SDK or later
建立 Razor 頁面專案Create a Razor Pages project
- Visual StudioVisual Studio
- Visual Studio CodeVisual Studio Code
- Visual Studio for MacVisual Studio for Mac
如需如何建立頁面專案的詳細指示,請參閱 開始使用 Razor 頁面 Razor 。See Get started with Razor Pages for detailed instructions on how to create a Razor Pages project.
Razor 頁面Razor Pages
Razor 啟動時,會啟用頁面 。 .cs:Razor Pages is enabled in Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
請考慮使用基本頁面:Consider a basic page:
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
上述程式碼看起來很像是在具有控制器和 views 的 ASP.NET Core 應用程式中使用的 Razor 視圖檔案。The preceding code looks a lot like a Razor view file used in an ASP.NET Core app with controllers and views. 這會讓它不同的是指示詞 @page
。What makes it different is the @page
directive. @page
會將檔案轉換成 MVC 動作,這表示它會直接處理要求,不用透過控制器。@page
makes the file into an MVC action - which means that it handles requests directly, without going through a controller. @page
必須是頁面上的第一個指示詞 Razor 。@page
must be the first Razor directive on a page. @page
會影響其他結構的行為 Razor 。@page
affects the behavior of other Razor constructs. Razor 分頁檔名的名稱必須是 cshtml 尾碼。Razor Pages file names have a .cshtml suffix.
使用PageModel
類別的類似頁面,顯示於下列兩個檔案中。A similar page, using a PageModel
class, is shown in the following two files. Pages/Index2.cshtml 檔案:The Pages/Index2.cshtml file:
@page
@using RazorPagesIntro.Pages
@model Index2Model
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Pages/Index2.cshtml.cs 頁面模型:The Pages/Index2.cshtml.cs page model:
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 }";
}
}
}
依照慣例,類別檔案的名稱會與 PageModel
Razor 附加 .cs 的分頁檔相同。By convention, the PageModel
class file has the same name as the Razor Page file with .cs appended. 例如,前一 Razor 頁是 Pages/index2.cshtml.cs。For example, the previous Razor Page is Pages/Index2.cshtml. 包含 PageModel
類別的檔案名為 Pages/Index2.cshtml.cs。The file containing the PageModel
class is named Pages/Index2.cshtml.cs.
頁面的 URL 路徑關聯是由頁面在檔案系統中的位置決定。The associations of URL paths to pages are determined by the page's location in the file system. 下表顯示 Razor 頁面路徑和相符的 URL:The following table shows a Razor Page path and the matching URL:
檔案名稱和路徑File name and path | 比對 URLmatching URL |
---|---|
/Pages/Index.cshtml/Pages/Index.cshtml | / 或 /Index / or /Index |
/Pages/Contact.cshtml/Pages/Contact.cshtml | /Contact |
/Pages/Store/Contact.cshtml/Pages/Store/Contact.cshtml | /Store/Contact |
/Pages/Store/Index.cshtml/Pages/Store/Index.cshtml | /Store 或 /Store/Index /Store or /Store/Index |
注意:Notes:
- 執行時間預設會 Razor 在 [ pages ] 資料夾中尋找分頁檔。The runtime looks for Razor Pages files in the Pages folder by default.
Index
是 URL 未包含頁面時的預設頁面。Index
is the default page when a URL doesn't include a page.
撰寫基本表單Write a basic form
Razor 頁面的設計目的是要讓搭配網頁瀏覽器使用的常見模式在建立應用程式時很容易執行。Razor Pages is designed to make common patterns used with web browsers easy to implement when building an app. 模型系結 、卷標協助程式和 HTML 協助程式全都 是 使用頁面類別中定義的屬性 Razor 。Model binding, Tag Helpers, and HTML helpers all just work with the properties defined in a Razor Page class. Contact
模型請考慮實作基本的「與我們連絡」格式頁面:Consider a page that implements a basic "contact us" form for the Contact
model:
本文件中的範例,會在 Startup.cs 檔案中初始化 DbContext
。For the samples in this document, the DbContext
is initialized in the Startup.cs file.
記憶體中的資料庫需要 Microsoft.EntityFrameworkCore.InMemory
NuGet 套件。The in memory database requires the Microsoft.EntityFrameworkCore.InMemory
NuGet package.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
services.AddRazorPages();
}
資料模型:The data model:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
DB 內容:The db context:
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Models;
namespace RazorPagesContacts.Data
{
public class CustomerDbContext : DbContext
{
public CustomerDbContext(DbContextOptions options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
}
Pages/Create.cshtml 檢視檔案:The Pages/Create.cshtml view file:
@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/Create.cshtml.cs 頁面模型:The Pages/Create.cshtml.cs page model:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
using RazorPagesContacts.Models;
using System.Threading.Tasks;
namespace RazorPagesContacts.Pages.Customers
{
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
依照慣例,PageModel
類別稱之為 <PageName>Model
,與頁面位於相同的命名空間。By convention, the PageModel
class is called <PageName>Model
and is in the same namespace as the page.
PageModel
類別可以分離頁面邏輯與頁面展示。The PageModel
class allows separation of the logic of a page from its presentation. 此類別會定義頁面的處理常式,以處理傳送至頁面的要求與用於轉譯頁面的資料。It defines page handlers for requests sent to the page and the data used to render the page. 這種分隔允許:This separation allows:
- 透過相依性 插入來管理頁面相依性。Managing of page dependencies through dependency injection.
- 單元測試Unit testing
在 POST
要求上執行的頁面具有 「處理常式方法」OnPostAsync
(當使用者張貼表單時)。The page has an OnPostAsync
handler method, which runs on POST
requests (when a user posts the form). 可以新增任何 HTTP 指令動詞的處理常式方法。Handler methods for any HTTP verb can be added. 最常見的處理常式包括:The most common handlers are:
OnGet
,初始化頁所需要的狀態。OnGet
to initialize state needed for the page. 在上述程式碼中,此OnGet
方法會顯示 CreateModel 的 cshtml Razor 頁面。In the preceding code, theOnGet
method displays the CreateModel.cshtml Razor Page.OnPost
,處理表單提交作業。OnPost
to handle form submissions.
Async
命名尾碼是選擇性的,但依照慣例通常用於非同步函式。The Async
naming suffix is optional but is often used by convention for asynchronous functions. 上述程式碼一般適用于 Razor 頁面。The preceding code is typical for Razor Pages.
如果您熟悉使用控制器和 views 的 ASP.NET apps:If you're familiar with ASP.NET apps using controllers and views:
OnPostAsync
上述範例中的程式碼看起來類似一般的控制器程式碼。TheOnPostAsync
code in the preceding example looks similar to typical controller code.- 大部分的 MVC 基本專案,例如 模型系結、 驗證和動作結果,其運作方式與控制器和 Razor 頁面相同。Most of the MVC primitives like model binding, validation, and action results work the same with Controllers and Razor Pages.
前一個 OnPostAsync
方法:The previous OnPostAsync
method:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
OnPostAsync
的基本流程:The basic flow of OnPostAsync
:
檢查驗證錯誤。Check for validation errors.
- 如果沒有任何錯誤,會儲存資料並重新導向。If there are no errors, save the data and redirect.
- 如果有錯誤,會再次顯示有驗證訊息的頁面。If there are errors, show the page again with validation messages. 在許多情況下,會在用戶端上偵測到驗證錯誤,且永遠不會提交到伺服器。In many cases, validation errors would be detected on the client, and never submitted to the server.
Pages/Create.cshtml 檢視檔案:The Pages/Create.cshtml view file:
@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/Create. cshtml 轉譯的 HTML:The rendered HTML from Pages/Create.cshtml:
<p>Enter a customer name:</p>
<form method="post">
Name:
<input type="text" data-val="true"
data-val-length="The field Name must be a string with a maximum length of 10."
data-val-length-max="10" data-val-required="The Name field is required."
id="Customer_Name" maxlength="10" name="Customer.Name" value="" />
<input type="submit" />
<input name="__RequestVerificationToken" type="hidden"
value="<Antiforgery token here>" />
</form>
在先前的程式碼中,張貼表單:In the previous code, posting the form:
包含有效資料:With valid data:
OnPostAsync
處理常式方法會呼叫 RedirectToPage helper 方法。TheOnPostAsync
handler method calls the RedirectToPage helper method.RedirectToPage
會傳回 RedirectToPageResult 的執行個體。RedirectToPage
returns an instance of RedirectToPageResult.RedirectToPage
:RedirectToPage
:- 是動作結果。Is an action result.
- 類似于
RedirectToAction
或RedirectToRoute
(用於控制器和 views) 。Is similar toRedirectToAction
orRedirectToRoute
(used in controllers and views). - 已針對頁面自訂。Is customized for pages. 在上述範例中,它會重新導向至根索引頁面 (
/Index
)。In the preceding sample, it redirects to the root Index page (/Index
). 產生頁面 URL一節會詳細說明RedirectToPage
。RedirectToPage
is detailed in the URL generation for Pages section.
傳遞至伺服器的驗證錯誤:With validation errors that are passed to the server:
OnPostAsync
處理常式方法會呼叫 Page helper 方法。TheOnPostAsync
handler method calls the Page helper method.Page
會傳回 PageResult 的執行個體。Page
returns an instance of PageResult. 傳回Page
類似於控制站中的動作傳回View
。ReturningPage
is similar to how actions in controllers returnView
.PageResult
這是處理常式方法的預設傳回型別。PageResult
is the default return type for a handler method. 傳回void
的處理常式方法會呈現頁面。A handler method that returnsvoid
renders the page.- 在上述範例中,不使用任何值張貼表單會導致 ModelState 傳回 false。In the preceding example, posting the form with no value results in ModelState.IsValid returning false. 在此範例中,用戶端上不會顯示任何驗證錯誤。In this sample, no validation errors are displayed on the client. 本檔稍後會討論驗證錯誤處理。Validation error handing is covered later in this document.
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _context.Customers.Add(Customer); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
使用用戶端驗證偵測到驗證錯誤:With validation errors detected by client side validation:
- 資料 不 會張貼至伺服器。Data is not posted to the server.
- 本檔稍後會說明用戶端驗證。Client-side validation is explained later in this document.
Customer
屬性使用 [BindProperty]
屬性來加入宣告模型系結:The Customer
property uses [BindProperty]
attribute to opt in to model binding:
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
[BindProperty]
不 應該用於包含不應由用戶端變更之屬性的模型。[BindProperty]
should not be used on models containing properties that should not be changed by the client. 如需詳細資訊,請參閱 大量指派。For more information, see Overposting.
Razor 依預設,頁面只會系結具有非動詞命令的屬性 GET
。Razor Pages, by default, bind properties only with non-GET
verbs. 系結至屬性不需要撰寫程式碼,就能將 HTTP 資料轉換成模型類型。Binding to properties removes the need to writing code to convert HTTP data to the model type. 透過使用相同的屬性呈現表單欄位 (<input asp-for="Customer.Name">
) 並接受輸入,繫結可以減少程式碼。Binding reduces code by using the same property to render form fields (<input asp-for="Customer.Name">
) and accept the input.
警告
基於安全性考量,您必須選擇將 GET
要求資料繫結到頁面模型屬性。For security reasons, you must opt in to binding GET
request data to page model properties. 請先驗證使用者輸入再將其對應至屬性。Verify user input before mapping it to properties. 當您 GET
針對依賴查詢字串或路由值的案例進行定址時,加入宣告系結會很有用。Opting into GET
binding is useful when addressing scenarios that rely on query string or route values.
若要系結要求的屬性 GET
,請將屬性 [BindProperty]
的 SupportsGet
屬性設定為 true
:To bind a property on GET
requests, set the [BindProperty]
attribute's SupportsGet
property to true
:
[BindProperty(SupportsGet = true)]
如需詳細資訊,請參閱 ASP.NET Core 社區站立會議: (YouTube) 的系結取得討論。For more information, see ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
檢查 Pages/Create. cshtml view 檔案:Reviewing the Pages/Create.cshtml view file:
@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>
- 在上述程式碼中, 輸入標記協助程式會將
<input asp-for="Customer.Name" />
HTML 元素系結<input>
至Customer.Name
模型運算式。In the preceding code, the input tag helper<input asp-for="Customer.Name" />
binds the HTML<input>
element to theCustomer.Name
model expression. @addTagHelper
讓標籤協助程式可供使用。@addTagHelper
makes Tag Helpers available.
首頁The home page
Index. cshtml 是首頁:Index.cshtml is the home page:
@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>
@foreach (var contact in Model.Customer)
{
<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 New</a>
</form>
已建立關聯的 PageModel
類別 (Index.cshtml.cs):The associated PageModel
class (Index.cshtml.cs):
public class IndexModel : PageModel
{
private readonly CustomerDbContext _context;
public IndexModel(CustomerDbContext context)
{
_context = context;
}
public IList<Customer> Customer { get; set; }
public async Task OnGetAsync()
{
Customer = await _context.Customers.ToListAsync();
}
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customers.FindAsync(id);
if (contact != null)
{
_context.Customers.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
}
此 索引的 cshtml 檔案包含下列標記:The Index.cshtml file contains the following markup:
<td>
<a /a>
錨點標籤協助程式使用 asp-route-{value}
屬性來產生編輯頁面的連結。The <a /a>
Anchor Tag Helper used the asp-route-{value}
attribute to generate a link to the Edit page. 該連結包含路由資料和連絡人識別碼。The link contains route data with the contact ID. 例如: https://localhost:5001/Edit/1
。For example, https://localhost:5001/Edit/1
. 標記 協助程式可讓伺服器端程式碼參與建立和轉譯檔案中的 HTML 元素 Razor 。Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files.
此 索引的 cshtml 檔案包含標記,以建立每個客戶連絡人的 [刪除] 按鈕:The Index.cshtml file contains markup to create a delete button for each customer contact:
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
<button type="submit" asp-page-handler="delete"
呈現的 HTML:The rendered HTML:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
在 HTML 中轉譯 [刪除] 按鈕時,其 formaction 包含下列參數:When the delete button is rendered in HTML, its formaction includes parameters for:
- 由屬性指定的客戶連絡人識別碼
asp-route-id
。The customer contact ID, specified by theasp-route-id
attribute. handler
屬性所指定的asp-page-handler
。Thehandler
, specified by theasp-page-handler
attribute.
選取按鈕時,表單 POST
要求會傳送至伺服器。When the button is selected, a form POST
request is sent to the server. 依照慣例,會依據配置 OnPost[handler]Async
,按 handler
參數的值來選取處理常式方法。By convention, the name of the handler method is selected based on the value of the handler
parameter according to the scheme OnPost[handler]Async
.
在此範例中,因為 handler
為 delete
,所以會使用 OnPostDeleteAsync
處理常式方法來處理 POST
要求。Because the handler
is delete
in this example, the OnPostDeleteAsync
handler method is used to process the POST
request. 若 asp-page-handler
設為其他值 (例如 remove
),則會選取名為 OnPostRemoveAsync
的處理常式方法。If the asp-page-handler
is set to a different value, such as remove
, a handler method with the name OnPostRemoveAsync
is selected.
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customers.FindAsync(id);
if (contact != null)
{
_context.Customers.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
OnPostDeleteAsync
方法:The OnPostDeleteAsync
method:
id
從查詢字串取得。Gets theid
from the query string.- 使用
FindAsync
在資料庫中查詢客戶連絡人。Queries the database for the customer contact withFindAsync
. - 如果找到客戶連絡人,則會將它移除,並更新資料庫。If the customer contact is found, it's removed and the database is updated.
- 呼叫 RedirectToPage 以重新導向至根索引頁 (
/Index
)。Calls RedirectToPage to redirect to the root Index page (/Index
).
編輯 cshtml 檔案The Edit.cshtml file
@page "{id:int}"
@model RazorPagesContacts.Pages.Customers.EditModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<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}"
指示詞。The first line contains the @page "{id:int}"
directive. 路由條件約束 "{id:int}"
通知頁面接受包含 int
路由資料的頁面要求。The routing constraint"{id:int}"
tells the page to accept requests to the page that contain int
route data. 如果頁面要求不包含可以轉換成 int
的路由資料,執行階段會傳回 HTTP 404 (找不到) 錯誤。If a request to the page doesn't contain route data that can be converted to an int
, the runtime returns an HTTP 404 (not found) error. 若要使識別碼成為選擇性,請將 ?
附加至路由條件約束:To make the ID optional, append ?
to the route constraint:
@page "{id:int?}"
編輯 cshtml .cs 檔案:The Edit.cshtml.cs file:
public class EditModel : PageModel
{
private readonly CustomerDbContext _context;
public EditModel(CustomerDbContext context)
{
_context = context;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Customer = await _context.Customers.FindAsync(id);
if (Customer == null)
{
return RedirectToPage("./Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw new Exception($"Customer {Customer.Id} not found!");
}
return RedirectToPage("./Index");
}
}
驗證Validation
驗證規則:Validation rules:
- 在模型類別中會以宣告方式指定。Are declaratively specified in the model class.
- 會在應用程式的任何位置強制執行。Are enforced everywhere in the app.
System.ComponentModel.DataAnnotations命名空間會提供一組內建的驗證屬性,這些屬性會以宣告方式套用至類別或屬性。The System.ComponentModel.DataAnnotations namespace provides a set of built-in validation attributes that are applied declaratively to a class or property. DataAnnotations 也包含格式化屬性 [DataType]
,例如格式化的說明,而且不提供任何驗證。DataAnnotations also contains formatting attributes like [DataType]
that help with formatting and don't provide any validation.
請考慮 Customer
模型:Consider the Customer
model:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
使用下列 Create. cshtml view 檔案:Using the following Create.cshtml view file:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer.Name"></span>
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
上述程式碼:The preceding code:
包含 jQuery 和 jQuery 驗證腳本。Includes jQuery and jQuery validation scripts.
使用
<div />
和<span />
標記 協助程式來啟用:Uses the<div />
and<span />
Tag Helpers to enable:- 用戶端驗證。Client-side validation.
- 轉譯時發生驗證錯誤。Validation error rendering.
產生下列 HTML:Generates the following HTML:
<p>Enter a customer name:</p> <form method="post"> Name: <input type="text" data-val="true" data-val-length="The field Name must be a string with a maximum length of 10." data-val-length-max="10" data-val-required="The Name field is required." id="Customer_Name" maxlength="10" name="Customer.Name" value="" /> <input type="submit" /> <input name="__RequestVerificationToken" type="hidden" value="<Antiforgery token here>" /> </form> <script src="/lib/jquery/dist/jquery.js"></script> <script src="/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
張貼沒有名稱值的建立表單時,會顯示錯誤訊息:「需要名稱欄位」。Posting the Create form without a name value displays the error message "The Name field is required." 在表單上。on the form. 如果在用戶端上啟用 JavaScript,則瀏覽器會顯示錯誤,而不會張貼至伺服器。If JavaScript is enabled on the client, the browser displays the error without posting to the server.
[StringLength(10)]
屬性會 data-val-length-max="10"
在呈現的 HTML 上產生。The [StringLength(10)]
attribute generates data-val-length-max="10"
on the rendered HTML. data-val-length-max
防止瀏覽器輸入超過指定的最大長度。data-val-length-max
prevents browsers from entering more than the maximum length specified. 如果使用 Fiddler 之類的工具來編輯和重新播放 post:If a tool such as Fiddler is used to edit and replay the post:
- 名稱超過10。With the name longer than 10.
- 錯誤訊息「功能變數名稱必須是最大長度為10的字串」。The error message "The field Name must be a string with a maximum length of 10." 」錯誤訊息。is returned.
請考慮下列 Movie
模型:Consider the following Movie
model:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string Rating { get; set; }
}
驗證屬性會指定在其套用的模型屬性上強制執行的行為:The validation attributes specify behavior to enforce on the model properties they're applied to:
Required
和MinimumLength
屬性工作表示屬性必須有值,但不會防止使用者輸入空白字元來滿足這種驗證。TheRequired
andMinimumLength
attributes indicate that a property must have a value, but nothing prevents a user from entering white space to satisfy this validation.RegularExpression
屬性則用來限制可輸入的字元。TheRegularExpression
attribute is used to limit what characters can be input. 在上述程式碼中,"Genre":In the preceding code, "Genre":- 必須指使用字母。Must only use letters.
- 第一個字母必須是大寫。The first letter is required to be uppercase. 不允許使用空格、數字和特殊字元。White space, numbers, and special characters are not allowed.
RegularExpression
"Rating":TheRegularExpression
"Rating":- 第一個字元必須為大寫字母。Requires that the first character be an uppercase letter.
- 允許後續空格中的特殊字元和數位。Allows special characters and numbers in subsequent spaces. "PG-13" 對分級而言有效,但不適用於 "Genre"。"PG-13" is valid for a rating, but fails for a "Genre".
Range
屬性會將值限制在指定的範圍內。TheRange
attribute constrains a value to within a specified range.StringLength
屬性會設定字串屬性的最大長度,並選擇性地設定其最小長度。TheStringLength
attribute sets the maximum length of a string property, and optionally its minimum length.實值型別 (如
decimal
、int
、float
、DateTime
) 原本就是必要項目,而且不需要[Required]
屬性。Value types (such asdecimal
,int
,float
,DateTime
) are inherently required and don't need the[Required]
attribute.
模型的 [建立] 頁面會顯示 Movie
具有無效值的錯誤:The Create page for the Movie
model shows displays errors with invalid values:
如需詳細資訊,請參閱For more information, see:
使用 OnGet 處理常式後援來處理 HEAD 要求Handle HEAD requests with an OnGet handler fallback
HEAD
要求可讓您取得特定資源的標頭。HEAD
requests allow retrieving the headers for a specific resource. 不同於 GET
要求,HEAD
要求不會傳回回應主體。Unlike GET
requests, HEAD
requests don't return a response body.
一般來說,會為 HEAD
要求建立及呼叫 OnHead
處理常式:Ordinarily, an OnHead
handler is created and called for HEAD
requests:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
RazorOnGet
如果未 OnHead
定義任何處理程式,則頁面會切換回呼叫處理常式。Razor Pages falls back to calling the OnGet
handler if no OnHead
handler is defined.
XSRF/CSRF 和 Razor PagesXSRF/CSRF and Razor Pages
Razor 頁面會受到 Antiforgery 驗證的保護。Razor Pages are protected by Antiforgery validation. FormTagHelper會將 antiforgery token 插入至 HTML 表單元素。The FormTagHelper injects antiforgery tokens into HTML form elements.
使用頁面的版面配置、部分、範本和標記協助程式 RazorUsing Layouts, partials, templates, and Tag Helpers with Razor Pages
頁面會使用 view engine 的所有功能 Razor 。Pages work with all the capabilities of the Razor view engine. 配置、部分、範本、標籤協助程式、 _ViewStart cshtml 和 _ViewImports. cshtml 的運作方式與傳統視圖的運作方式相同。 RazorLayouts, partials, templates, Tag Helpers, _ViewStart.cshtml, and _ViewImports.cshtml work in the same way they do for conventional Razor views.
可利用這些功能的一部分來整理這個頁面。Let's declutter this page by taking advantage of some of those capabilities.
將 版面配置頁面新增至 Pages/Shared/_Layout.cshtml:Add a layout page to Pages/Shared/_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>RP Sample</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
<a asp-page="/Index">Home</a>
<a asp-page="/Customers/Create">Create</a>
<a asp-page="/Customers/Index">Customers</a> <br />
@RenderBody()
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</body>
</html>
- 控制每個頁面的版面配置 (除非頁面退出版面配置)。Controls the layout of each page (unless the page opts out of layout).
- 匯入 HTML 結構,例如 JavaScript 和樣式表。Imports HTML structures such as JavaScript and stylesheets.
- 頁面的內容 Razor 會轉譯
@RenderBody()
為呼叫的位置。The contents of the Razor page are rendered where@RenderBody()
is called.
如需詳細資訊,請參閱 版面配置頁面。For more information, see layout page.
版面配置屬性是在 Pages/_ViewStart.cshtml 中設定:The Layout property is set in Pages/_ViewStart.cshtml:
@{
Layout = "_Layout";
}
版面配置位於 Pages/Shared 資料夾。The layout is in the Pages/Shared folder. 頁面會以階層方式尋找其他檢視 (版面配置、範本、部分),從目前頁面的相同資料夾開始。Pages look for other views (layouts, templates, partials) hierarchically, starting in the same folder as the current page. 頁面/共用 資料夾中的版面配置可以從 Razor [ pages ] 資料夾下的任何頁面使用。A layout in the Pages/Shared folder can be used from any Razor page under the Pages folder.
版面配置頁面應位於 Pages/Shared 資料夾中。The layout file should go in the Pages/Shared folder.
我們 不 建議您將配置檔案放入 Views/Shared 資料夾。We recommend you not put the layout file in the Views/Shared folder. Views/Shared 是 MVC 檢視模式。Views/Shared is an MVC views pattern. Razor 頁面的目的是要依賴資料夾階層,不是路徑慣例。Razor Pages are meant to rely on folder hierarchy, not path conventions.
頁面上的視圖搜尋 Razor 包含 Pages 資料夾。View search from a Razor Page includes the Pages folder. 適用于 MVC 控制器和傳統視圖的版面配置、範本和 Razor 部分 只會運作。The layouts, templates, and partials used with MVC controllers and conventional Razor views just work.
新增 Pages/_ViewImports.cshtml 檔案:Add a Pages/_ViewImports.cshtml file:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
本教學課程稍後會說明 @namespace
。@namespace
is explained later in the tutorial. @addTagHelper
指示詞會將 內建標記協助程式帶入 Pages 資料夾中的所有頁面。The @addTagHelper
directive brings in the built-in Tag Helpers to all the pages in the Pages folder.
在 @namespace
頁面上設定的指示詞:The @namespace
directive set on a page:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
指示詞會 @namespace
設定頁面的命名空間。The @namespace
directive sets the namespace for the page. @model
指示詞不需要包含命名空間。The @model
directive doesn't need to include the namespace.
當 @namespace
指示詞包含在 _ViewImports.cshtml 中時,指定的命名空間會在匯入 @namespace
指示詞的頁面中提供所產生之命名空間的前置詞。When the @namespace
directive is contained in _ViewImports.cshtml, the specified namespace supplies the prefix for the generated namespace in the Page that imports the @namespace
directive. 所產生命名空間的其餘部分 (後置字元部分) 是包含 _ViewImports.cshtml 的資料夾和包含頁面的資料夾之間,以句點分隔的相對路徑。The rest of the generated namespace (the suffix portion) is the dot-separated relative path between the folder containing _ViewImports.cshtml and the folder containing the page.
例如,PageModel
類別 Pages/Customers/Edit.cshtml.cs 會明確地設定命名空間:For example, the PageModel
class Pages/Customers/Edit.cshtml.cs explicitly sets the namespace:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
Pages/_ViewImports.cshtml 檔案會設定下列命名空間:The Pages/_ViewImports.cshtml file sets the following namespace:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
針對 Pages/Customers/Edit. cshtml 頁面產生的命名空間與 Razor PageModel
類別相同。The generated namespace for the Pages/Customers/Edit.cshtml Razor Page is the same as the PageModel
class.
@namespace
也可搭配傳統 Razor 視圖使用。@namespace
also works with conventional Razor views.
請考慮 Pages/Create. cshtml view 檔案:Consider the Pages/Create.cshtml view file:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer.Name"></span>
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
更新的 Pages/Create. cshtml view 檔案,其中包含 _ViewImports. cshtml 和先前的版面配置檔案:The updated Pages/Create.cshtml view file with _ViewImports.cshtml and the preceding layout file:
@page
@model CreateModel
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
在上述程式碼中, _ViewImports 的 cshtml 已匯入命名空間和標記協助程式。In the preceding code, the _ViewImports.cshtml imported the namespace and Tag Helpers. 設定檔案匯入 JavaScript 檔案。The layout file imported the JavaScript files.
Razor Pages 入門專案包含 pages/_ValidationScriptsPartial. cshtml,可連結用戶端驗證。The Razor Pages starter project contains the Pages/_ValidationScriptsPartial.cshtml, which hooks up client-side validation.
如需部分檢視的詳細資訊,請參閱 ASP.NET Core 中的部分檢視。For more information on partial views, see ASP.NET Core 中的部分檢視.
產生頁面 URLURL generation for Pages
前面出現過的 Create
頁面使用 RedirectToPage
:The Create
page, shown previously, uses RedirectToPage
:
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
應用程式有下列檔案/資料夾結構:The app has the following file/folder structure:
/Pages/Pages
Index.cshtmlIndex.cshtml
隱私權. cshtmlPrivacy.cshtml
/Customers/Customers
- Create.cshtmlCreate.cshtml
- Edit.cshtmlEdit.cshtml
- Index.cshtmlIndex.cshtml
Pages/customers/Create. cshtml 和 Pages/customers/Edit. cshtml 頁面會在成功之後重新導向至 Pages/customers/Index。 cshtml 。The Pages/Customers/Create.cshtml and Pages/Customers/Edit.cshtml pages redirect to Pages/Customers/Index.cshtml after success. 字串 ./Index
是用來存取前一個頁面的相對頁面名稱。The string ./Index
is a relative page name used to access the preceding page. 它是用來產生 Pages/Customers/Index. cshtml 頁面的 url。It is used to generate URLs to the Pages/Customers/Index.cshtml page. 例如:For example:
Url.Page("./Index", ...)
<a asp-page="./Index">Customers Index Page</a>
RedirectToPage("./Index")
絕對頁面名稱 /Index
是用來產生 Pages/Index. cshtml 頁面的 url。The absolute page name /Index
is used to generate URLs to the Pages/Index.cshtml page. 例如:For example:
Url.Page("/Index", ...)
<a asp-page="/Index">Home Index Page</a>
RedirectToPage("/Index")
頁面名稱是從根 /Pages 資料夾到該頁面的路徑 (包括前置的 /
,例如 /Index
)。The page name is the path to the page from the root /Pages folder including a leading /
(for example, /Index
). 上述的 URL 產生範例提供增強的選項和功能功能,而不是硬式編碼 URL。The preceding URL generation samples offer enhanced options and functional capabilities over hard-coding a URL. URL 產生使用路由,可以根據路由在目的地路徑中定義的方式,產生並且編碼參數。URL generation uses routing and can generate and encode parameters according to how the route is defined in the destination path.
產生頁面 URL 支援相關的名稱。URL generation for pages supports relative names. 下表顯示使用 RedirectToPage
Pages/Customers/Create. cshtml 中的不同參數所選取的索引頁面。The following table shows which Index page is selected using different RedirectToPage
parameters in Pages/Customers/Create.cshtml.
RedirectToPage(x)RedirectToPage(x) | 頁面Page |
---|---|
RedirectToPage("/Index")RedirectToPage("/Index") | Pages/IndexPages/Index |
RedirectToPage("./Index");RedirectToPage("./Index"); | Pages/Customers/IndexPages/Customers/Index |
RedirectToPage("../Index")RedirectToPage("../Index") | Pages/IndexPages/Index |
RedirectToPage("Index")RedirectToPage("Index") | Pages/Customers/IndexPages/Customers/Index |
RedirectToPage("Index")
、 RedirectToPage("./Index")
和 RedirectToPage("../Index")
是 相對名稱。RedirectToPage("Index")
, RedirectToPage("./Index")
, and RedirectToPage("../Index")
are relative names. RedirectToPage
參數「結合」了目前頁面的路徑,以計算目的地頁面的名稱。The RedirectToPage
parameter is combined with the path of the current page to compute the name of the destination page.
相對名稱連結在以複雜結構建置網站時很有用。Relative name linking is useful when building sites with a complex structure. 當使用相對名稱連結資料夾中的頁面時:When relative names are used to link between pages in a folder:
- 重新命名資料夾並不會中斷相對連結。Renaming a folder doesn't break the relative links.
- 連結不會中斷,因為它們不包含資料夾名稱。Links are not broken because they don't include the folder name.
若要重新導向到不同區域中的頁面,請指定區域:To redirect to a page in a different Area, specify the area:
RedirectToPage("/Index", new { area = "Services" });
如需詳細資訊,請參閱 ASP.NET Core 中的區域 和 Razor ASP.NET Core 中的頁面路由和應用程式慣例。For more information, see ASP.NET Core 中的區域 and Razor ASP.NET Core 中的頁面路由和應用程式慣例.
ViewData 屬性ViewData attribute
您可以使用將資料傳遞至頁面 ViewDataAttribute 。Data can be passed to a page with ViewDataAttribute. 具有屬性的屬性(property) [ViewData]
會從儲存和載入其值 ViewDataDictionary 。Properties with the [ViewData]
attribute have their values stored and loaded from the ViewDataDictionary.
在下列範例中,會將 AboutModel
[ViewData]
屬性套用至 Title
屬性:In the following example, the AboutModel
applies the [ViewData]
attribute to the Title
property:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
在 [關於] 頁面上,存取 Title
屬性作為模型屬性:In the About page, access the Title
property as a model property:
<h1>@Model.Title</h1>
在此配置中,標題會從 ViewData 字典中讀取:In the layout, the title is read from the ViewData dictionary:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempDataTempData
ASP.NET Core 會公開 TempData 。ASP.NET Core exposes the TempData. 這個屬性會儲存資料,直到讀取為止。This property stores data until it's read. Keep 和 Peek 方法可以用來檢查資料,不用刪除。The Keep and Peek methods can be used to examine the data without deletion. TempData
當需要多個單一要求的資料時,適用于重新導向。TempData
is useful for redirection, when data is needed for more than a single request.
下列程式碼會設定使用 TempData
的 Message
值:The following code sets the value of Message
using TempData
:
public class CreateDotModel : PageModel
{
private readonly AppDbContext _db;
public CreateDotModel(AppDbContext db)
{
_db = db;
}
[TempData]
public string Message { get; set; }
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
Message = $"Customer {Customer.Name} added";
return RedirectToPage("./Index");
}
}
Pages/Customers/Index.cshtml 檔案中的下列標記會顯示使用 TempData
的 Message
值。The following markup in the Pages/Customers/Index.cshtml file displays the value of Message
using TempData
.
<h3>Msg: @Model.Message</h3>
Pages/Customers/Index.cshtml.cs 頁面模型會將 [TempData]
屬性 (attribute) 套用到 Message
屬性 (property)。The Pages/Customers/Index.cshtml.cs page model applies the [TempData]
attribute to the Message
property.
[TempData]
public string Message { get; set; }
如需詳細資訊,請參閱 TempData。For more information, see TempData.
每頁面有多個處理常式Multiple handlers per page
下列頁面會使用 asp-page-handler
標記協助程式為兩個處理常式產生標記:The following page generates markup for two handlers using the asp-page-handler
Tag Helper:
@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>
上例中的表單有兩個提交按鈕,每一個都使用 FormActionTagHelper
提交至不同的 URL。The form in the preceding example has two submit buttons, each using the FormActionTagHelper
to submit to a different URL. asp-page-handler
屬性附隨於 asp-page
。The asp-page-handler
attribute is a companion to asp-page
. asp-page-handler
產生的 URL 會提交至頁面所定義的每一個處理常式方法。asp-page-handler
generates URLs that submit to each of the handler methods defined by a page. 因為範例連結至目前的頁面,所以未指定 asp-page
。asp-page
isn't specified because the sample is linking to the current page.
頁面模型:The page model:
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;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostJoinListAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
public async Task<IActionResult> OnPostJoinListUCAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Customer.Name = Customer.Name?.ToUpperInvariant();
return await OnPostJoinListAsync();
}
}
}
上述程式碼使用「具名的處理常式方法」。The preceding code uses named handler methods. 具名的處理常式方法的建立方式是採用名稱中在 On<HTTP Verb>
後面、Async
之前 (如有) 的文字。Named handler methods are created by taking the text in the name after On<HTTP Verb>
and before Async
(if present). 在上例中,頁面方法是 OnPost JoinList Async 和 OnPost JoinListUC Async。In the preceding example, the page methods are OnPost JoinList Async and OnPost JoinListUC Async. 移除 OnPost 和 Async,處理常式名稱就是 JoinList
和 JoinListUC
。With OnPost and Async removed, the handler names are JoinList
and JoinListUC
.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
使用上述程式碼,提交至 OnPostJoinListAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH?handler=JoinList
。Using the preceding code, the URL path that submits to OnPostJoinListAsync
is https://localhost:5001/Customers/CreateFATH?handler=JoinList
. 提交至 OnPostJoinListUCAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
。The URL path that submits to OnPostJoinListUCAsync
is https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
.
自訂路由Custom routes
使用 @page
指示詞,可以:Use the @page
directive to:
- 指定頁面的自訂路由。Specify a custom route to a page. 例如,[關於] 頁面的路由可使用
@page "/Some/Other/Path"
設為/Some/Other/Path
。For example, the route to the About page can be set to/Some/Other/Path
with@page "/Some/Other/Path"
. - 將區段附加到頁面的預設路由。Append segments to a page's default route. 例如,使用
@page "item"
可將 "item" 區段新增到頁面的預設路由。For example, an "item" segment can be added to a page's default route with@page "item"
. - 將參數附加到頁面的預設路由。Append parameters to a page's default route. 例如,具有
@page "{id}"
的頁面可要求識別碼參數id
。For example, an ID parameter,id
, can be required for a page with@page "{id}"
.
支援在路徑開頭以波狀符號 (~
) 指定根相對路徑。A root-relative path designated by a tilde (~
) at the beginning of the path is supported. 例如,@page "~/Some/Other/Path"
與 @page "/Some/Other/Path"
相同。For example, @page "~/Some/Other/Path"
is the same as @page "/Some/Other/Path"
.
如果您不喜歡 URL 中的查詢字串 ?handler=JoinList
,請變更路由,將處理常式名稱放在 url 的路徑部分。If you don't like the query string ?handler=JoinList
in the URL, change the route to put the handler name in the path portion of the URL. 您可以藉由新增以雙引號括住的路由範本來自訂路由 @page
。The route can be customized by adding a route template enclosed in double quotes after the @page
directive.
@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>
使用上述程式碼,提交至 OnPostJoinListAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH/JoinList
。Using the preceding code, the URL path that submits to OnPostJoinListAsync
is https://localhost:5001/Customers/CreateFATH/JoinList
. 提交至 OnPostJoinListUCAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH/JoinListUC
。The URL path that submits to OnPostJoinListUCAsync
is https://localhost:5001/Customers/CreateFATH/JoinListUC
.
跟在 handler
後面的 ?
表示路由參數為選擇性。The ?
following handler
means the route parameter is optional.
Advanced configuration and settingsAdvanced configuration and settings
大部分的應用程式都不需要下列各節中的設定和設定。The configuration and settings in following sections is not required by most apps.
若要設定 advanced 選項,請使用設定的多載 AddRazorPages RazorPagesOptions :To configure advanced options, use the AddRazorPages overload that configures RazorPagesOptions:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
}
使用 RazorPagesOptions 設定頁面的根目錄,或新增頁面的應用程式模型慣例。Use the RazorPagesOptions to set the root directory for pages, or add application model conventions for pages. 如需慣例的詳細資訊,請參閱 Razor 頁面授權慣例。For more information on conventions, see Razor Pages authorization conventions.
若要先行編譯視圖,請參閱 Razor view 編譯。To precompile views, see Razor view compilation.
指定 Razor 頁面位於內容根目錄Specify that Razor Pages are at the content root
根據預設, Razor 頁面會根目錄在 /Pages 目錄中。By default, Razor Pages are rooted in the /Pages directory. 加入 WithRazorPagesAtContentRoot ,以指定您的 Razor 頁面位於應用程式的 內容根目錄 (ContentRootPath) :Add WithRazorPagesAtContentRoot to specify that your Razor Pages are at the content root (ContentRootPath) of the app:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesAtContentRoot();
}
指定 Razor 頁面位於自訂根目錄Specify that Razor Pages are at a custom root directory
新增 WithRazorPagesRoot 以指定 Razor 頁面位於應用程式的自訂根目錄, (提供相對路徑) :Add WithRazorPagesRoot to specify that Razor Pages are at a custom root directory in the app (provide a relative path):
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesRoot("/path/to/razor/pages");
}
其他資源Additional resources
- 請參閱這篇簡介中的 開始使用 Razor 頁面。See Get started with Razor Pages, which builds on this introduction.
- 授權屬性和 Razor 頁面Authorize attribute and Razor Pages
- 下載或查看範例程式碼Download or view sample code
- ASP.NET Core 簡介
- Razor ASP.NET Core 的語法參考
- ASP.NET Core 中的區域
- 教學課程:開始使用 Razor ASP.NET Core 中的頁面
- Razor ASP.NET Core 中的頁面授權慣例
- Razor ASP.NET Core 中的頁面路由和應用程式慣例
- Razor ASP.NET Core 中的頁面單元測試
- ASP.NET Core 中的部分檢視
- ASP.NET Core 元件的已呈現和整合 Razor
- Visual StudioVisual Studio
- Visual Studio CodeVisual Studio Code
- Visual Studio for MacVisual Studio for Mac
- ASP.NET 和 網頁程式開發 工作負載的 Visual Studio 2019Visual Studio 2019 with the ASP.NET and web development workload
- .NET Core SDK 2.2 或更新版本.NET Core SDK 2.2 or later
警告
如果您使用 Visual Studio 2017,請參閱 dotnet/sdk 問題 #3124 (英文),以取得未使用 Visual Studio 的 .NET Core SDK 版本相關資訊。If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.
建立 Razor 頁面專案Create a Razor Pages project
- Visual StudioVisual Studio
- Visual Studio for MacVisual Studio for Mac
- Visual Studio CodeVisual Studio Code
如需如何建立頁面專案的詳細指示,請參閱 開始使用 Razor 頁面 Razor 。See Get started with Razor Pages for detailed instructions on how to create a Razor Pages project.
Razor 頁面Razor Pages
Razor 啟動時,會啟用頁面 。 .cs:Razor Pages is enabled in Startup.cs:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Includes support for Razor Pages and controllers.
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
請考慮使用基本頁面:Consider a basic page:
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
上述程式碼看起來很像是在具有控制器和 views 的 ASP.NET Core 應用程式中使用的 Razor 視圖檔案。The preceding code looks a lot like a Razor view file used in an ASP.NET Core app with controllers and views. 讓它不同的是 @page
指示詞。What makes it different is the @page
directive. @page
會將檔案轉換成 MVC 動作,這表示它會直接處理要求,不用透過控制器。@page
makes the file into an MVC action - which means that it handles requests directly, without going through a controller. @page
必須是頁面上的第一個指示詞 Razor 。@page
must be the first Razor directive on a page. @page
會影響其他結構的行為 Razor 。@page
affects the behavior of other Razor constructs.
使用PageModel
類別的類似頁面,顯示於下列兩個檔案中。A similar page, using a PageModel
class, is shown in the following two files. Pages/Index2.cshtml 檔案:The Pages/Index2.cshtml file:
@page
@using RazorPagesIntro.Pages
@model IndexModel2
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Pages/Index2.cshtml.cs 頁面模型:The Pages/Index2.cshtml.cs page model:
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
namespace RazorPagesIntro.Pages
{
public class IndexModel2 : PageModel
{
public string Message { get; private set; } = "PageModel in C#";
public void OnGet()
{
Message += $" Server time is { DateTime.Now }";
}
}
}
依照慣例,類別檔案的名稱會與 PageModel
Razor 附加 .cs 的分頁檔相同。By convention, the PageModel
class file has the same name as the Razor Page file with .cs appended. 例如,前一 Razor 頁是 Pages/index2.cshtml.cs。For example, the previous Razor Page is Pages/Index2.cshtml. 包含 PageModel
類別的檔案名為 Pages/Index2.cshtml.cs。The file containing the PageModel
class is named Pages/Index2.cshtml.cs.
頁面的 URL 路徑關聯是由頁面在檔案系統中的位置決定。The associations of URL paths to pages are determined by the page's location in the file system. 下表顯示 Razor 頁面路徑和相符的 URL:The following table shows a Razor Page path and the matching URL:
檔案名稱和路徑File name and path | 比對 URLmatching URL |
---|---|
/Pages/Index.cshtml/Pages/Index.cshtml | / 或 /Index / or /Index |
/Pages/Contact.cshtml/Pages/Contact.cshtml | /Contact |
/Pages/Store/Contact.cshtml/Pages/Store/Contact.cshtml | /Store/Contact |
/Pages/Store/Index.cshtml/Pages/Store/Index.cshtml | /Store 或 /Store/Index /Store or /Store/Index |
注意:Notes:
- 執行時間預設會 Razor 在 [ pages ] 資料夾中尋找分頁檔。The runtime looks for Razor Pages files in the Pages folder by default.
Index
是 URL 未包含頁面時的預設頁面。Index
is the default page when a URL doesn't include a page.
撰寫基本表單Write a basic form
Razor 頁面的設計目的是要讓搭配網頁瀏覽器使用的常見模式在建立應用程式時很容易執行。Razor Pages is designed to make common patterns used with web browsers easy to implement when building an app. 模型系結 、卷標協助程式和 HTML 協助程式全都 是 使用頁面類別中定義的屬性 Razor 。Model binding, Tag Helpers, and HTML helpers all just work with the properties defined in a Razor Page class. Contact
模型請考慮實作基本的「與我們連絡」格式頁面:Consider a page that implements a basic "contact us" form for the Contact
model:
本文件中的範例,會在 Startup.cs 檔案中初始化 DbContext
。For the samples in this document, the DbContext
is initialized in the Startup.cs file.
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();
}
}
}
資料模型:The data model:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Data
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(100)]
public string Name { get; set; }
}
}
DB 內容:The db context:
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 檢視檔案:The Pages/Create.cshtml view file:
@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 頁面模型:The Pages/Create.cshtml.cs page model:
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;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
}
}
依照慣例,PageModel
類別稱之為 <PageName>Model
,與頁面位於相同的命名空間。By convention, the PageModel
class is called <PageName>Model
and is in the same namespace as the page.
PageModel
類別可以分離頁面邏輯與頁面展示。The PageModel
class allows separation of the logic of a page from its presentation. 此類別會定義頁面的處理常式,以處理傳送至頁面的要求與用於轉譯頁面的資料。It defines page handlers for requests sent to the page and the data used to render the page. 這種分隔允許:This separation allows:
- 透過相依性 插入來管理頁面相依性。Managing of page dependencies through dependency injection.
- 單元測試 頁面。Unit testing the pages.
在 POST
要求上執行的頁面具有 「處理常式方法」OnPostAsync
(當使用者張貼表單時)。The page has an OnPostAsync
handler method, which runs on POST
requests (when a user posts the form). 您可以新增任何 HTTP 指令動詞的處理常式方法。You can add handler methods for any HTTP verb. 最常見的處理常式包括:The most common handlers are:
OnGet
,初始化頁所需要的狀態。OnGet
to initialize state needed for the page. OnGet 範例。OnGet sample.OnPost
,處理表單提交作業。OnPost
to handle form submissions.
Async
命名尾碼是選擇性的,但依照慣例通常用於非同步函式。The Async
naming suffix is optional but is often used by convention for asynchronous functions. 上述程式碼一般適用于 Razor 頁面。The preceding code is typical for Razor Pages.
如果您熟悉使用控制器和 views 的 ASP.NET apps:If you're familiar with ASP.NET apps using controllers and views:
OnPostAsync
上述範例中的程式碼看起來類似一般的控制器程式碼。TheOnPostAsync
code in the preceding example looks similar to typical controller code.- 大部分的 MVC 基本專案,例如 模型系結、 驗證、 驗證和動作結果都是共用的。Most of the MVC primitives like model binding, validation, Validation, and action results are shared.
前一個 OnPostAsync
方法:The previous OnPostAsync
method:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
OnPostAsync
的基本流程:The basic flow of OnPostAsync
:
檢查驗證錯誤。Check for validation errors.
- 如果沒有任何錯誤,會儲存資料並重新導向。If there are no errors, save the data and redirect.
- 如果有錯誤,會再次顯示有驗證訊息的頁面。If there are errors, show the page again with validation messages. 用戶端驗證和傳統的 ASP.NET Core MVC 應用程式完全相同。Client-side validation is identical to traditional ASP.NET Core MVC applications. 在許多情況下,會在用戶端上偵測到驗證錯誤,且永遠不會提交到伺服器。In many cases, validation errors would be detected on the client, and never submitted to the server.
成功輸入資料後,OnPostAsync
處理常式方法會呼叫 RedirectToPage
協助程式方法,傳回 RedirectToPageResult
的執行個體。When the data is entered successfully, the OnPostAsync
handler method calls the RedirectToPage
helper method to return an instance of RedirectToPageResult
. RedirectToPage
是新的動作結果,類似於 RedirectToAction
或 RedirectToRoute
,但會針對頁面自訂。RedirectToPage
is a new action result, similar to RedirectToAction
or RedirectToRoute
, but customized for pages. 在上述範例中,它會重新導向至根索引頁面 (/Index
)。In the preceding sample, it redirects to the root Index page (/Index
). 產生頁面 URL一節會詳細說明 RedirectToPage
。RedirectToPage
is detailed in the URL generation for Pages section.
當提交的表單有驗證錯誤時 (傳遞至伺服器),OnPostAsync
處理常式方法會呼叫 Page
協助程式方法。When the submitted form has validation errors (that are passed to the server), theOnPostAsync
handler method calls the Page
helper method. Page
會傳回 PageResult
的執行個體。Page
returns an instance of PageResult
. 傳回 Page
類似於控制站中的動作傳回 View
。Returning Page
is similar to how actions in controllers return View
. PageResult
這是處理常式方法的預設傳回型別。PageResult
is the default return type for a handler method. 傳回 void
的處理常式方法會呈現頁面。A handler method that returns void
renders the page.
Customer
屬性 (property) 使用 [BindProperty]
屬性 (attribute) 加入模型繫結。The Customer
property uses [BindProperty]
attribute to opt in to model binding.
public class CreateModel : PageModel
{
private readonly AppDbContext _db;
public CreateModel(AppDbContext db)
{
_db = db;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
}
Razor 依預設,頁面只會系結具有非動詞命令的屬性 GET
。Razor Pages, by default, bind properties only with non-GET
verbs. 繫結至屬性可以減少您必須撰寫的程式碼數量。Binding to properties can reduce the amount of code you have to write. 透過使用相同的屬性呈現表單欄位 (<input asp-for="Customer.Name">
) 並接受輸入,繫結可以減少程式碼。Binding reduces code by using the same property to render form fields (<input asp-for="Customer.Name">
) and accept the input.
警告
基於安全性考量,您必須選擇將 GET
要求資料繫結到頁面模型屬性。For security reasons, you must opt in to binding GET
request data to page model properties. 請先驗證使用者輸入再將其對應至屬性。Verify user input before mapping it to properties. 當您 GET
針對依賴查詢字串或路由值的案例進行定址時,加入宣告系結會很有用。Opting into GET
binding is useful when addressing scenarios that rely on query string or route values.
若要系結要求的屬性 GET
,請將屬性 [BindProperty]
的 SupportsGet
屬性設定為 true
:To bind a property on GET
requests, set the [BindProperty]
attribute's SupportsGet
property to true
:
[BindProperty(SupportsGet = true)]
如需詳細資訊,請參閱 ASP.NET Core 社區站立會議: (YouTube) 的系結取得討論。For more information, see ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
首頁 (Index.cshtml):The home page (Index.cshtml):
@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>
已建立關聯的 PageModel
類別 (Index.cshtml.cs):The associated PageModel
class (Index.cshtml.cs):
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 檔案包含下列標記可為每個連絡人建立編輯連結:The Index.cshtml file contains the following markup to create an edit link for each contact:
<a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a>
錨點標籤協助程式使用 asp-route-{value}
屬性來產生編輯頁面的連結。The <a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a>
Anchor Tag Helper used the asp-route-{value}
attribute to generate a link to the Edit page. 該連結包含路由資料和連絡人識別碼。The link contains route data with the contact ID. 例如: https://localhost:5001/Edit/1
。For example, https://localhost:5001/Edit/1
. 標記 協助程式可讓伺服器端程式碼參與建立和轉譯檔案中的 HTML 元素 Razor 。Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files. 標記協助程式由 @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
啟用Tag Helpers are enabled by @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Pages/Edit.cshtml 檔案:The Pages/Edit.cshtml file:
@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}"
指示詞。The first line contains the @page "{id:int}"
directive. 路由條件約束 "{id:int}"
通知頁面接受包含 int
路由資料的頁面要求。The routing constraint"{id:int}"
tells the page to accept requests to the page that contain int
route data. 如果頁面要求不包含可以轉換成 int
的路由資料,執行階段會傳回 HTTP 404 (找不到) 錯誤。If a request to the page doesn't contain route data that can be converted to an int
, the runtime returns an HTTP 404 (not found) error. 若要使識別碼成為選擇性,請將 ?
附加至路由條件約束:To make the ID optional, append ?
to the route constraint:
@page "{id:int?}"
Pages/Edit.cshtml.cs 檔案:The Pages/Edit.cshtml.cs file:
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;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Customer = await _db.Customers.FindAsync(id);
if (Customer == null)
{
return RedirectToPage("/Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Attach(Customer).State = EntityState.Modified;
try
{
await _db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw new Exception($"Customer {Customer.Id} not found!");
}
return RedirectToPage("/Index");
}
}
}
Index.cshtml 檔案也包含能夠為每個客戶連絡人建立刪除按鈕的標記:The Index.cshtml file also contains markup to create a delete button for each customer contact:
<button type="submit" asp-page-handler="delete"
asp-route-id="@contact.Id">delete</button>
使用 HTML 轉譯刪除按鈕時,其 formaction
會包含下列項目的參數:When the delete button is rendered in HTML, its formaction
includes parameters for:
asp-route-id
屬性指定的客戶連絡人識別碼。The customer contact ID specified by theasp-route-id
attribute.asp-page-handler
屬性指定的handler
。Thehandler
specified by theasp-page-handler
attribute.
以下是轉譯的刪除按鈕範例,內含客戶連絡人識別碼 1
:Here is an example of a rendered delete button with a customer contact ID of 1
:
<button type="submit" formaction="/?id=1&handler=delete">delete</button>
選取按鈕時,表單 POST
要求會傳送至伺服器。When the button is selected, a form POST
request is sent to the server. 依照慣例,會依據配置 OnPost[handler]Async
,按 handler
參數的值來選取處理常式方法。By convention, the name of the handler method is selected based on the value of the handler
parameter according to the scheme OnPost[handler]Async
.
在此範例中,因為 handler
為 delete
,所以會使用 OnPostDeleteAsync
處理常式方法來處理 POST
要求。Because the handler
is delete
in this example, the OnPostDeleteAsync
handler method is used to process the POST
request. 若 asp-page-handler
設為其他值 (例如 remove
),則會選取名為 OnPostRemoveAsync
的處理常式方法。If the asp-page-handler
is set to a different value, such as remove
, a handler method with the name OnPostRemoveAsync
is selected. 下列程式碼顯示 OnPostDeleteAsync
處理常式:The following code shows the OnPostDeleteAsync
handler:
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
方法:The OnPostDeleteAsync
method:
- 接受查詢字串的
id
。Accepts theid
from the query string. 如果 Index. cshtml 頁面指示詞包含路由條件約束"{id:int?}"
,則id
會來自路由資料。If the Index.cshtml page directive contained routing constraint"{id:int?}"
,id
would come from route data. 的路由資料id
是在 URI 中指定,例如https://localhost:5001/Customers/2
。The route data forid
is specified in the URI such ashttps://localhost:5001/Customers/2
. - 使用
FindAsync
在資料庫中查詢客戶連絡人。Queries the database for the customer contact withFindAsync
. - 若找到客戶連絡人,會從客戶連絡人清單中予以移除。If the customer contact is found, they're removed from the list of customer contacts. 資料庫隨即更新。The database is updated.
- 呼叫
RedirectToPage
以重新導向至根索引頁 (/Index
)。CallsRedirectToPage
to redirect to the root Index page (/Index
).
將頁面屬性標示為必要Mark page properties as required
上的屬性 PageModel
可以使用 必要 的屬性標記:Properties on a PageModel
can be marked with the Required attribute:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
namespace RazorPagesMovie.Pages.Movies
{
public class CreateModel : PageModel
{
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
[Required(ErrorMessage = "Color is required")]
public string Color { get; set; }
public IActionResult OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
// Process color.
return RedirectToPage("./Index");
}
}
}
如需詳細資訊,請參閱模型驗證。For more information, see Model validation.
使用 OnGet 處理常式後援來處理 HEAD 要求Handle HEAD requests with an OnGet handler fallback
HEAD
要求可讓您擷取特定資源的標頭。HEAD
requests allow you to retrieve the headers for a specific resource. 不同於 GET
要求,HEAD
要求不會傳回回應主體。Unlike GET
requests, HEAD
requests don't return a response body.
一般來說,會為 HEAD
要求建立及呼叫 OnHead
處理常式:Ordinarily, an OnHead
handler is created and called for HEAD
requests:
public void OnHead()
{
HttpContext.Response.Headers.Add("HandledBy", "Handled by OnHead!");
}
在 ASP.NET Core 2.1 或更新版本中, Razor OnGet
如果未定義任何處理程式,頁面就會切換回呼叫處理常式 OnHead
。In ASP.NET Core 2.1 or later, Razor Pages falls back to calling the OnGet
handler if no OnHead
handler is defined. 這個行為藉由在 Startup.ConfigureServices
中呼叫 SetCompatibilityVersion 來啟用:This behavior is enabled by the call to SetCompatibilityVersion in Startup.ConfigureServices
:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
預設範本會在 ASP.NET Core 2.1 和 2.2 中產生 SetCompatibilityVersion
呼叫。The default templates generate the SetCompatibilityVersion
call in ASP.NET Core 2.1 and 2.2. SetCompatibilityVersion
有效地將 Razor Pages 選項設定 AllowMappingHeadRequestsToGetHandler
為 true
。SetCompatibilityVersion
effectively sets the Razor Pages option AllowMappingHeadRequestsToGetHandler
to true
.
您可以明確選擇「特定」行為,而不必透過 SetCompatibilityVersion
選擇所有行為。Rather than opting in to all behaviors with SetCompatibilityVersion
, you can explicitly opt in to specific behaviors. 下列程式碼會選擇讓 HEAD
要求對應到 OnGet
處理常式:The following code opts in to allowing HEAD
requests to be mapped to the OnGet
handler:
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.AllowMappingHeadRequestsToGetHandler = true;
});
XSRF/CSRF 和 Razor PagesXSRF/CSRF and Razor Pages
您不必撰寫任何防偽驗證程式碼。You don't have to write any code for antiforgery validation. Antiforgery 權杖的產生和驗證會自動包含在 Razor 頁面中。Antiforgery token generation and validation are automatically included in Razor Pages.
使用頁面的版面配置、部分、範本和標記協助程式 RazorUsing Layouts, partials, templates, and Tag Helpers with Razor Pages
頁面會使用 view engine 的所有功能 Razor 。Pages work with all the capabilities of the Razor view engine. 配置、部分、範本、標籤協助程式、 _ViewStart cshtml、 _ViewImports. cshtml 的運作方式與傳統視圖的運作方式相同。 RazorLayouts, partials, templates, Tag Helpers, _ViewStart.cshtml, _ViewImports.cshtml work in the same way they do for conventional Razor views.
可利用這些功能的一部分來整理這個頁面。Let's declutter this page by taking advantage of some of those capabilities.
將 版面配置頁面新增至 Pages/Shared/_Layout.cshtml:Add a layout page to Pages/Shared/_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>Razor Pages Sample</title>
</head>
<body>
<a asp-page="/Index">Home</a>
@RenderBody()
<a asp-page="/Customers/Create">Create</a> <br />
</body>
</html>
- 控制每個頁面的版面配置 (除非頁面退出版面配置)。Controls the layout of each page (unless the page opts out of layout).
- 匯入 HTML 結構,例如 JavaScript 和樣式表。Imports HTML structures such as JavaScript and stylesheets.
如需詳細資訊,請參閱版面配置頁面。See layout page for more information.
版面配置屬性是在 Pages/_ViewStart.cshtml 中設定:The Layout property is set in Pages/_ViewStart.cshtml:
@{
Layout = "_Layout";
}
版面配置位於 Pages/Shared 資料夾。The layout is in the Pages/Shared folder. 頁面會以階層方式尋找其他檢視 (版面配置、範本、部分),從目前頁面的相同資料夾開始。Pages look for other views (layouts, templates, partials) hierarchically, starting in the same folder as the current page. 頁面/共用 資料夾中的版面配置可以從 Razor [ pages ] 資料夾下的任何頁面使用。A layout in the Pages/Shared folder can be used from any Razor page under the Pages folder.
版面配置頁面應位於 Pages/Shared 資料夾中。The layout file should go in the Pages/Shared folder.
我們 不 建議您將配置檔案放入 Views/Shared 資料夾。We recommend you not put the layout file in the Views/Shared folder. Views/Shared 是 MVC 檢視模式。Views/Shared is an MVC views pattern. Razor 頁面的目的是要依賴資料夾階層,不是路徑慣例。Razor Pages are meant to rely on folder hierarchy, not path conventions.
頁面上的視圖搜尋 Razor 包含 Pages 資料夾。View search from a Razor Page includes the Pages folder. 您使用 MVC 控制器和傳統視圖的版面配置、範本和部分, Razor 只是工作。The layouts, templates, and partials you're using with MVC controllers and conventional Razor views just work.
新增 Pages/_ViewImports.cshtml 檔案:Add a Pages/_ViewImports.cshtml file:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
本教學課程稍後會說明 @namespace
。@namespace
is explained later in the tutorial. @addTagHelper
指示詞會將 內建標記協助程式帶入 Pages 資料夾中的所有頁面。The @addTagHelper
directive brings in the built-in Tag Helpers to all the pages in the Pages folder.
在頁面上明確使用 @namespace
指示詞時:When the @namespace
directive is used explicitly on a page:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
指示詞會設定頁面的命名空間。The directive sets the namespace for the page. @model
指示詞不需要包含命名空間。The @model
directive doesn't need to include the namespace.
當 @namespace
指示詞包含在 _ViewImports.cshtml 中時,指定的命名空間會在匯入 @namespace
指示詞的頁面中提供所產生之命名空間的前置詞。When the @namespace
directive is contained in _ViewImports.cshtml, the specified namespace supplies the prefix for the generated namespace in the Page that imports the @namespace
directive. 所產生命名空間的其餘部分 (後置字元部分) 是包含 _ViewImports.cshtml 的資料夾和包含頁面的資料夾之間,以句點分隔的相對路徑。The rest of the generated namespace (the suffix portion) is the dot-separated relative path between the folder containing _ViewImports.cshtml and the folder containing the page.
例如,PageModel
類別 Pages/Customers/Edit.cshtml.cs 會明確地設定命名空間:For example, the PageModel
class Pages/Customers/Edit.cshtml.cs explicitly sets the namespace:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
Pages/_ViewImports.cshtml 檔案會設定下列命名空間:The Pages/_ViewImports.cshtml file sets the following namespace:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
針對 Pages/Customers/Edit. cshtml 頁面產生的命名空間與 Razor PageModel
類別相同。The generated namespace for the Pages/Customers/Edit.cshtml Razor Page is the same as the PageModel
class.
@namespace
也可搭配傳統 Razor 視圖使用。@namespace
also works with conventional Razor views.
原始的 Pages/Create.cshtml 檢視檔案:The original Pages/Create.cshtml view file:
@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 檢視檔案:The updated Pages/Create.cshtml view file:
@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 Pages 入門專案包含 pages/_ValidationScriptsPartial. cshtml,可連結用戶端驗證。The Razor Pages starter project contains the Pages/_ValidationScriptsPartial.cshtml, which hooks up client-side validation.
如需部分檢視的詳細資訊,請參閱 ASP.NET Core 中的部分檢視。For more information on partial views, see ASP.NET Core 中的部分檢視.
產生頁面 URLURL generation for Pages
前面出現過的 Create
頁面使用 RedirectToPage
:The Create
page, shown previously, uses RedirectToPage
:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
應用程式有下列檔案/資料夾結構:The app has the following file/folder structure:
/Pages/Pages
Index.cshtmlIndex.cshtml
/Customers/Customers
- Create.cshtmlCreate.cshtml
- Edit.cshtmlEdit.cshtml
- Index.cshtmlIndex.cshtml
Pages/Customers/Create.cshtml 和 Pages/Customers/Edit.cshtml 頁面在成功後會重新導向至 Pages/Index.cshtml。The Pages/Customers/Create.cshtml and Pages/Customers/Edit.cshtml pages redirect to Pages/Index.cshtml after success. 字串 /Index
為 URI 的一部分,可存取前一個頁面。The string /Index
is part of the URI to access the preceding page. 字串 /Index
可以用來產生 Pages/Index.cshtml 頁面的 URI。The string /Index
can be used to generate URIs to the Pages/Index.cshtml page. 例如:For example:
Url.Page("/Index", ...)
<a asp-page="/Index">My Index Page</a>
RedirectToPage("/Index")
頁面名稱是從根 /Pages 資料夾到該頁面的路徑 (包括前置的 /
,例如 /Index
)。The page name is the path to the page from the root /Pages folder including a leading /
(for example, /Index
). 上述 URL 產生範例,透過硬式編碼的 URL 提供更加優異的選項與功能。The preceding URL generation samples offer enhanced options and functional capabilities over hardcoding a URL. URL 產生使用路由,可以根據路由在目的地路徑中定義的方式,產生並且編碼參數。URL generation uses routing and can generate and encode parameters according to how the route is defined in the destination path.
產生頁面 URL 支援相關的名稱。URL generation for pages supports relative names. 下表顯示從 Pages/Customers/Create.cshtml 以不同的 RedirectToPage
參數選取的索引頁:The following table shows which Index page is selected with different RedirectToPage
parameters from Pages/Customers/Create.cshtml:
RedirectToPage(x)RedirectToPage(x) | 頁面Page |
---|---|
RedirectToPage("/Index")RedirectToPage("/Index") | Pages/IndexPages/Index |
RedirectToPage("./Index");RedirectToPage("./Index"); | Pages/Customers/IndexPages/Customers/Index |
RedirectToPage("../Index")RedirectToPage("../Index") | Pages/IndexPages/Index |
RedirectToPage("Index")RedirectToPage("Index") | Pages/Customers/IndexPages/Customers/Index |
RedirectToPage("Index")
、RedirectToPage("./Index")
和 RedirectToPage("../Index")
是「相對名稱」。RedirectToPage("Index")
, RedirectToPage("./Index")
, and RedirectToPage("../Index")
are relative names. RedirectToPage
參數「結合」了目前頁面的路徑,以計算目的地頁面的名稱。The RedirectToPage
parameter is combined with the path of the current page to compute the name of the destination page.
相對名稱連結在以複雜結構建置網站時很有用。Relative name linking is useful when building sites with a complex structure. 如果您使用相對名稱連結資料夾中的頁面,您可以重新命名該資料夾。If you use relative names to link between pages in a folder, you can rename that folder. 所有連結仍可運作 (因為它們不包含資料夾名稱)。All the links still work (because they didn't include the folder name).
若要重新導向到不同區域中的頁面,請指定區域:To redirect to a page in a different Area, specify the area:
RedirectToPage("/Index", new { area = "Services" });
如需詳細資訊,請參閱ASP.NET Core 中的區域。For more information, see ASP.NET Core 中的區域.
ViewData 屬性ViewData attribute
資料可以傳遞至具有 ViewDataAttribute 的頁面。Data can be passed to a page with ViewDataAttribute. Razor具有屬性之控制器或頁面模型上的屬性 [ViewData]
會從>viewdatadictionary儲存和載入其值。Properties on controllers or Razor Page models with the [ViewData]
attribute have their values stored and loaded from the ViewDataDictionary.
在下列範例中, AboutModel
包含標示為的 Title
屬性 [ViewData]
。In the following example, the AboutModel
contains a Title
property marked with [ViewData]
. Title
屬性會設定為 [關於] 頁面的標題:The Title
property is set to the title of the About page:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
在 [關於] 頁面上,存取 Title
屬性作為模型屬性:In the About page, access the Title
property as a model property:
<h1>@Model.Title</h1>
在此配置中,標題會從 ViewData 字典中讀取:In the layout, the title is read from the ViewData dictionary:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempDataTempData
ASP.NET Core 公開控制器上的 TempData 屬性。ASP.NET Core exposes the TempData property on a controller. 這個屬性會儲存資料,直到讀取為止。This property stores data until it's read. Keep
和 Peek
方法可以用來檢查資料,不用刪除。The Keep
and Peek
methods can be used to examine the data without deletion. 當有多個要求需要資料時,TempData
對重新導向很有幫助。TempData
is useful for redirection, when data is needed for more than a single request.
下列程式碼會設定使用 TempData
的 Message
值:The following code sets the value of Message
using TempData
:
public class CreateDotModel : PageModel
{
private readonly AppDbContext _db;
public CreateDotModel(AppDbContext db)
{
_db = db;
}
[TempData]
public string Message { get; set; }
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
Message = $"Customer {Customer.Name} added";
return RedirectToPage("./Index");
}
}
Pages/Customers/Index.cshtml 檔案中的下列標記會顯示使用 TempData
的 Message
值。The following markup in the Pages/Customers/Index.cshtml file displays the value of Message
using TempData
.
<h3>Msg: @Model.Message</h3>
Pages/Customers/Index.cshtml.cs 頁面模型會將 [TempData]
屬性 (attribute) 套用到 Message
屬性 (property)。The Pages/Customers/Index.cshtml.cs page model applies the [TempData]
attribute to the Message
property.
[TempData]
public string Message { get; set; }
如需詳細資訊,請參閱 TempData。For more information, see TempData .
每頁面有多個處理常式Multiple handlers per page
下列頁面會使用 asp-page-handler
標記協助程式為兩個處理常式產生標記:The following page generates markup for two handlers using the asp-page-handler
Tag Helper:
@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>
上例中的表單有兩個提交按鈕,每一個都使用 FormActionTagHelper
提交至不同的 URL。The form in the preceding example has two submit buttons, each using the FormActionTagHelper
to submit to a different URL. asp-page-handler
屬性附隨於 asp-page
。The asp-page-handler
attribute is a companion to asp-page
. asp-page-handler
產生的 URL 會提交至頁面所定義的每一個處理常式方法。asp-page-handler
generates URLs that submit to each of the handler methods defined by a page. 因為範例連結至目前的頁面,所以未指定 asp-page
。asp-page
isn't specified because the sample is linking to the current page.
頁面模型:The page model:
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;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostJoinListAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
public async Task<IActionResult> OnPostJoinListUCAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Customer.Name = Customer.Name?.ToUpperInvariant();
return await OnPostJoinListAsync();
}
}
}
上述程式碼使用「具名的處理常式方法」。The preceding code uses named handler methods. 具名的處理常式方法的建立方式是採用名稱中在 On<HTTP Verb>
後面、Async
之前 (如有) 的文字。Named handler methods are created by taking the text in the name after On<HTTP Verb>
and before Async
(if present). 在上例中,頁面方法是 OnPost JoinList Async 和 OnPost JoinListUC Async。In the preceding example, the page methods are OnPost JoinList Async and OnPost JoinListUC Async. 移除 OnPost 和 Async,處理常式名稱就是 JoinList
和 JoinListUC
。With OnPost and Async removed, the handler names are JoinList
and JoinListUC
.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
使用上述程式碼,提交至 OnPostJoinListAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH?handler=JoinList
。Using the preceding code, the URL path that submits to OnPostJoinListAsync
is https://localhost:5001/Customers/CreateFATH?handler=JoinList
. 提交至 OnPostJoinListUCAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
。The URL path that submits to OnPostJoinListUCAsync
is https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
.
自訂路由Custom routes
使用 @page
指示詞,可以:Use the @page
directive to:
- 指定頁面的自訂路由。Specify a custom route to a page. 例如,[關於] 頁面的路由可使用
@page "/Some/Other/Path"
設為/Some/Other/Path
。For example, the route to the About page can be set to/Some/Other/Path
with@page "/Some/Other/Path"
. - 將區段附加到頁面的預設路由。Append segments to a page's default route. 例如,使用
@page "item"
可將 "item" 區段新增到頁面的預設路由。For example, an "item" segment can be added to a page's default route with@page "item"
. - 將參數附加到頁面的預設路由。Append parameters to a page's default route. 例如,具有
@page "{id}"
的頁面可要求識別碼參數id
。For example, an ID parameter,id
, can be required for a page with@page "{id}"
.
支援在路徑開頭以波狀符號 (~
) 指定根相對路徑。A root-relative path designated by a tilde (~
) at the beginning of the path is supported. 例如,@page "~/Some/Other/Path"
與 @page "/Some/Other/Path"
相同。For example, @page "~/Some/Other/Path"
is the same as @page "/Some/Other/Path"
.
如果您不喜歡 URL 中的查詢字串 ?handler=JoinList
,請變更路由,將處理常式名稱放在 url 的路徑部分。If you don't like the query string ?handler=JoinList
in the URL, change the route to put the handler name in the path portion of the URL. 您可以藉由新增以雙引號括住的路由範本來自訂路由 @page
。The route can be customized by adding a route template enclosed in double quotes after the @page
directive.
@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>
使用上述程式碼,提交至 OnPostJoinListAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH/JoinList
。Using the preceding code, the URL path that submits to OnPostJoinListAsync
is https://localhost:5001/Customers/CreateFATH/JoinList
. 提交至 OnPostJoinListUCAsync
的 URL 路徑是 https://localhost:5001/Customers/CreateFATH/JoinListUC
。The URL path that submits to OnPostJoinListUCAsync
is https://localhost:5001/Customers/CreateFATH/JoinListUC
.
跟在 handler
後面的 ?
表示路由參數為選擇性。The ?
following handler
means the route parameter is optional.
組態與設定Configuration and settings
若要設定進階選項,請在 MVC 產生器上使用擴充方法 AddRazorPagesOptions
:To configure advanced options, use the extension method AddRazorPagesOptions
on the MVC builder:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
}
目前可以使用 RazorPagesOptions
設定頁面的根目錄,或新增頁面的應用程式模型慣例。Currently you can use the RazorPagesOptions
to set the root directory for pages, or add application model conventions for pages. 我們將在未來以這種方式獲得更多的擴充性。We'll enable more extensibility this way in the future.
若要先行編譯視圖,請參閱 Razor view 編譯。To precompile views, see Razor view compilation .
下載或檢視範例程式碼。Download or view sample code.
請參閱這篇簡介中的 開始使用 Razor 頁面。See Get started with Razor Pages, which builds on this introduction.
指定 Razor 頁面位於內容根目錄Specify that Razor Pages are at the content root
根據預設, Razor 頁面會根目錄在 /Pages 目錄中。By default, Razor Pages are rooted in the /Pages directory. 將 Razor PagesAtContentRoot 新增至 >addmvc ,以指定您的 Razor 頁面位於應用程式的 內容根目錄 (ContentRootPath) :Add WithRazorPagesAtContentRoot to AddMvc to specify that your Razor Pages are at the content root (ContentRootPath) of the app:
services.AddMvc()
.AddRazorPagesOptions(options =>
{
...
})
.WithRazorPagesAtContentRoot();
指定 Razor 頁面位於自訂根目錄Specify that Razor Pages are at a custom root directory
將 Razor PagesRoot 新增至 >addmvc ,以指定您 Razor 的頁面位於應用程式中的自訂根目錄, (提供相對路徑) :Add WithRazorPagesRoot to AddMvc to specify that your Razor Pages are at a custom root directory in the app (provide a relative path):
services.AddMvc()
.AddRazorPagesOptions(options =>
{
...
})
.WithRazorPagesRoot("/path/to/razor/pages");