??Razor頁(yè)面應(yīng)用是MVC框架的一種簡(jiǎn)化應(yīng)用输拇,與傳統(tǒng)Web開發(fā)模式相似摘符,以頁(yè)面為單位來劃分應(yīng)用功能。
自定義Razor頁(yè)面的根目錄
??Razor頁(yè)面在項(xiàng)目中的默認(rèn)存儲(chǔ)路徑是/Pages目錄策吠,即所有頁(yè)面必須放在該目錄下逛裤。而請(qǐng)求的URL中是不包含根目錄名字的,例如某個(gè)頁(yè)面文件路徑為 /Pages/News/List.cshtml ,那么請(qǐng)求該頁(yè)面的URL應(yīng)為 http://<域名/端口>/News/List猴抹。
??如果不想將Razor頁(yè)面放到/Pages目錄下带族,可通過RazorPagesOptions
選項(xiàng)類的RootDirectory
屬性來配置自定義頁(yè)面存放路徑,也可用擴(kuò)展方法簡(jiǎn)單配置蟀给。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//services.AddMvc();
//services.PostConfigure<RazorPagesOptions>(option=>
//{
// option.RootDirectory = "/CustPages";
//});
services.AddMvc().WithRazorPagesRoot("/CustPages");
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
Razor頁(yè)面與頁(yè)面模型關(guān)聯(lián)
??Razor代碼文件只要在文檔首行加上@page指令蝙砌,并且將頁(yè)面放在程序所配置的根目錄下,就可以在URL中訪問了跋理。
??如果頁(yè)面涉及相對(duì)復(fù)雜的業(yè)務(wù)邏輯處理择克,就需要?jiǎng)?chuàng)建一個(gè)頁(yè)面模型類來編寫?yīng)毩⒌奶幚泶a,使得視圖與代碼分離前普。頁(yè)面模型類需要從PageModel
類派生肚邢。通過聲明約定的方法與視圖邏輯交互,通過名為handler
的路由參數(shù)來調(diào)用這些方法拭卿。
??一般命名規(guī)則為:On<HTTP method><handler name>[Async]
骡湖。
- 方法以“On”開頭。
- 緊接著是HTTP-method峻厚,如GET勺鸦、POST、DELETE等目木。
- 然后是“正式名稱”换途,此名稱可直接作為路由參數(shù)handler的值懊渡。
- 如果是異步方法,可用Async結(jié)尾军拟。
??例如剃执,OnGet,OnGetStudentInfos懈息,OnPostFileAsync等肾档。
??頁(yè)面模型類還可公開屬性,便于視圖代碼綁定辫继。由于HTTP往返通信是無狀態(tài)的怒见,此過程中屬性值通常會(huì)丟失,希望保留的話可在屬性上加BindPropertyAttribute
特性姑宽。
??在Razor頁(yè)面上通過@model指令讓視圖與頁(yè)面模型類關(guān)聯(lián)起來遣耍,如@model TestModel
。
??項(xiàng)目模板在添加新Razor頁(yè)面時(shí)炮车,一般會(huì)生產(chǎn)一個(gè)與頁(yè)面名字相同的頁(yè)面模型類舵变。如,添加一個(gè)Test.cshtml的頁(yè)面瘦穆,就會(huì)生成一個(gè)Test.cshtml.cs類纪隙,是從PageModel類派生的。
public class TestModel : PageModel
{
#region 屬性
[BindProperty]
public string ProductName { get; set; }
[BindProperty]
public DateTime ProductDate { get; set; }
[BindProperty]
public Guid ProductID { get; set; }
[BindProperty]
public string ProductFamily { get; set; }
#endregion
public void OnGet()
{
ProductID = Guid.NewGuid();
ProductName = "<未知產(chǎn)品>";
ProductDate = DateTime.Today;
ProductFamily = "<未知分類>";
}
public void OnPost()
{
ViewData["msg"] = "恭喜你扛或,提交成功";
}
}
@page
@using Demo
@model TestModel
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>測(cè)試頁(yè)面</title>
</head>
<body>
<form method="post">
產(chǎn)品編號(hào):<input type="text" readonly asp-for="ProductID"/><br/>
產(chǎn)品名稱:<input type="text" asp-for="ProductName"/><br/>
生產(chǎn)日期:<input type="text" asp-for="ProductDate"/><br/>
產(chǎn)品分類:<input asp-for="ProductFamily"/><br/>
<br/><br/>
<input type="submit" value="提交"/>
</form>
<div>
@{
if (ViewData.ContainsKey("msg"))
{
<p>@ViewData["msg"].ToString()</p>
}
}
</div>
</body>
</html>
Razor Page應(yīng)用的路由映射
??當(dāng)Razor Page項(xiàng)目的URL路徑較長(zhǎng)的時(shí)候绵咱,可以使用路由映射來縮短。
- 如下在方法中注冊(cè)與MVC相關(guān)的服務(wù)熙兔,并且添加路由映射配置麸拄。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddRazorPagesOptions(o =>
{
o.Conventions
.AddPageRoute("/Start", "/")
.AddPageRoute("/Users/NewUser", "/regnew")
.AddPageRoute("/Users/UserList", "/showlist");
});
}
??AddPageRoute
方法的第一個(gè)參數(shù)是真實(shí)頁(yè)面地址,第二個(gè)參數(shù)是路由之后的新地址黔姜。如果將路由映射為“/”或者空字符串拢切,就可以使該頁(yè)面變成主頁(yè)。
通過@page指令設(shè)置Razor頁(yè)面的URL路由
??在@page指令之后秆吵,可以使用字符串實(shí)例來指定路由映射淮椰。
??(1)直接指定路徑段,表示該路由是相對(duì)于當(dāng)前頁(yè)面的纳寂。例如主穗,指定字符串“renew”,當(dāng)前頁(yè)面是Orders毙芜,那么最終訪問的URL為 http://demo.net/orders/renew 忽媒。
??(2)如果指定的字符是以“/”或者“~/”開頭,則表示其路由是相對(duì)于根URL的腋粥。例如晦雨,頁(yè)面/users/admin架曹,而指定的路由為“/admin”,那么訪問的URL為 http://demo.net/admin 闹瞧。
- 例
??Pages目錄下添加一個(gè) Main.cshtml绑雄。
@page "/"
<html>
<body>
<h2>主頁(yè)</h2>
<div>
<a href="/musics">我的音樂</a>
<a href="/photos">我的照片</a>
</div>
</body>
</html>
??Pages目錄下添加一個(gè)Funcs目錄,F(xiàn)uncs下添加 MyMusics.cshtml 和 MyPhotos.cshtml奥邮。
@page "/musics"
<html>
<body>
<h2>我的音樂</h2>
</body>
</html>
@page "/photos"
<html>
<body>
<h2>我的照片</h2>
</body>
</html>
自定義頁(yè)面的handler方法
??在頁(yè)面模型中万牺,OnGet、OnPost等方法會(huì)根據(jù)頁(yè)面的請(qǐng)求方法自動(dòng)被調(diào)用洽腺。
??但是這些約定的方法有時(shí)不能滿足開發(fā)需求脚粟,因此框架允許自定義這些方法的名稱努潘,在路由數(shù)據(jù)字典中遥缕,這些頁(yè)面方法被命名為handler。默認(rèn)情況下時(shí)通過URL的請(qǐng)求參數(shù)來調(diào)用頁(yè)面方法的绪爸,例如度液,http://localhost/students?handler=UploadPic 厕宗,其中students是頁(yè)面名画舌,UploadPic是方法名堕担,實(shí)際方法命名應(yīng)為OnGetUploadPic。
??如果不希望URL中出現(xiàn)handler字段曲聂,可通過@page指令來自定義路由霹购,例如,@page "{handler?}"
朋腋,handler是路由字典參數(shù)齐疙,必須寫在一對(duì)大括號(hào)中,后面的問號(hào)表示該值為可選旭咽。URL可變?yōu)?http://localhost/students/UploadPic 贞奋。
??在實(shí)際使用時(shí),可以使用擴(kuò)展標(biāo)記幫助器在運(yùn)行時(shí)自動(dòng)生成URL穷绵,例如轿塔,asp-page標(biāo)記屬性指定要執(zhí)行的頁(yè)面,當(dāng)前頁(yè)面可以忽略仲墨,asp-page-handler
標(biāo)記屬性指定要執(zhí)行的handler的名稱勾缭。
- 例
@page "{handler?}"
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
@model Demo.TestModel
<html>
<body>
<form method="post">
用戶名:
<input type="text" name="username" /><br />
密碼:
<input type="password" name="password"/><br/>
<div>
<input type="submit" value="公開登錄" asp-page-handler="LoginPublic"/>
<input type="submit" value="隱身登錄" asp-page-handler="LoginHidden"/>
</div>
</form>
</body>
</html>
??test頁(yè)面在兩個(gè)提交按鈕上,通過asp-page-handler標(biāo)記屬性來指定要調(diào)用的方法目养,由于處理的方法將在當(dāng)前頁(yè)面的模型類中定義俩由,所以不需要asp-page標(biāo)記。
public class TestModel : PageModel
{
public ActionResult OnPostLoginPublic(string username, string password)
{
string msg = $"你以公共方式登錄癌蚁,輸入的用戶名為{username}幻梯,密碼為{password}";
return Content(msg);
}
public ActionResult OnPostLoginHidden(string username, string password)
{
string msg = $"你以隱身方式登錄兜畸,輸入的用戶名為{username},密碼為{password}";
return Content(msg);
}
}