MVC 架構(gòu)
MVC架構(gòu)把 App 按照邏輯分成三層:
- Controllers,接收 http request,配合 model,通過(guò)http response 返回 view,盡量不做別的事
- Models, 負(fù)責(zé)業(yè)務(wù)邏輯,App 的狀態(tài),以及數(shù)據(jù)處理
- Views,呈現(xiàn) UI,如果UI 較復(fù)雜,應(yīng)該使用View 組件, ViewModel, 或者 view 模板
Controller
ASP.NET Core MVC 中的所有 Controller 都繼承于 Controller 基類,而 ASP.NET Core WEB API 中的 Controller 都繼承于 ControllerBase 基類,是因?yàn)镃ontroller 基類支持 View。
Controller 可以返回三種類型的結(jié)果:
- HTTP 狀態(tài)碼 或者 Redirect 結(jié)果
- View 或者 格式化的結(jié)果(比如:Json(customer))
- 與 Client 請(qǐng)求協(xié)商的結(jié)果
View
View 是使用 Razor 引擎標(biāo)記的 HTML 模板頁(yè)面。
Razor 引擎標(biāo)記在服務(wù)端生成 HTML。
HMTL 中的 Razor 標(biāo)記以 @ 開頭,中間是{ … }。比如:
@{
ViewData["Title"] = "About";
}
具體語(yǔ)法參考:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-8.0#razor-syntax
ASP.NET Core MVC 中的一個(gè) View 是一個(gè) .cshtml 代碼文件。
一般一個(gè) Controller 對(duì)應(yīng)一個(gè) View 文件夾,一個(gè)Action 可能對(duì)應(yīng)一個(gè) View。
View 的文件夾結(jié)構(gòu)一般是:Views/[ControllerName] 。
多個(gè) Controller 共享的 View 放在 Views/Shared 中。
View 的名稱一般與 Action 的名稱相同。
如果Action返回的 View 不指定具體View名稱,則返回與 Action 方法相同的 View。
此時(shí) ASP.NET Core 會(huì)從Views/[ControllerName]和Views/Shared 中查找同名 View。
return View();
Action 也可以顯示指定 View 名稱:
return View("Orders");
Action 顯示指定 View 名稱的時(shí)候,使用相對(duì)路徑:
return View("../Manage/Index");
或者:
return View("./About");
Action 也可以不指定名稱,但指定 Model:
return View(Orders);
Action 也可以同時(shí)指定名稱和 Model:
return View("Orders", Orders);
向 View 傳遞數(shù)據(jù)可以使用強(qiáng)類型的 ViewModel 或者弱類型的 ViewData
ViewModel
也可以向 View 傳一個(gè) ViewModel,ViewModel是用于 View 的強(qiáng)類型 Model。
強(qiáng)類型意味著每個(gè)View 中的變量都在Model有對(duì)應(yīng)的定義,使用 @model 指令:
@model WebApplication1.ViewModels.Address
<h2>Contact</h2>
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
然后通過(guò) return View(ViewModel) 傳遞給View:
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel);
}
ViewModel 類一般就是一個(gè) POCO 類,即只有屬性,沒有方法的數(shù)據(jù)類。
ViewData
ViewData 是一個(gè)kv 結(jié)構(gòu)的字典結(jié)構(gòu)數(shù)據(jù)。
弱類型意味著即使 View 中找不到數(shù)據(jù),也不會(huì)報(bào)錯(cuò)。
比如在 View 中使用的ViewData[“Greeting”]和ViewData[“Address”]:
@{
// Since Address isn't a string, it requires a cast.
var address = ViewData["Address"] as Address;
}
@ViewData["Greeting"] World!
<address>
@address.Name<br>
@address.Street<br>
@address.City, @address.State @address.PostalCode
</address>
通過(guò) Action 中定義后通過(guò)return View() 傳給 View:
public IActionResult SomeAction()
{
ViewData["Greeting"] = "Hello";
ViewData["Address"] = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
也可以通過(guò)ViewData 屬性定義:
public class HomeController : Controller
{
[ViewData]
public string Title { get; set; }
public IActionResult About()
{
Title = "About Us";
ViewData["Message"] = "Your application description page.";
return View();
}
}
Partial View
當(dāng)需要拆分大型 View 或者復(fù)用小型View時(shí),可以使用 Partial View功能。
Partial View 中沒有 @page 指令。
Partial View 不運(yùn)行 _ViewStart.cshtml。
Partial View 的名稱通常以下劃線 _ 開頭。
Action 返回 Partial View:
public IActionResult OnGetPartial() =>
Partial("_AuthorPartialRP");
在 View 中通過(guò) Tag Helper 使用 Partial View:
<partial name="_PartialName" />
Partial View 的搜索路徑
MVC 中:
- /Areas//Views/
- /Areas//Views/Shared
- /Views/Shared
- /Pages/Shared
Razer Page 中:
- 當(dāng)前頁(yè)面文件夾
- 當(dāng)前頁(yè)面的上一級(jí)文件夾
- /Shared
- /Pages/Shared
- /Views/Shared
異步 HTML Helper
使用HTML Helper時(shí),一般使用 PartialAsync。
PartialAsync 返回 Task 類型的 IHtmlContent。
@await Html.PartialAsync("_PartialName")
Layout
Web App 一般都有布局,類似這樣:
默認(rèn)的布局文件名放在 Views/Shared/_Layout.cshtml 。
Layout 中一般會(huì)調(diào)用:
@RenderBody()
Layout 中可以引用多個(gè)部分,每個(gè)部分通過(guò)RenderSection替換:
<script type="text/javascript" src="~/scripts/global.js"></script>
@RenderSection("Scripts", required: false)
路由 Routing
路由的作用是把客戶端的 http 請(qǐng)求 url 映射到Controllers的具體類的具體 Action 上。
路由語(yǔ)法可以參考 https://blog.csdn.net/cuit/article/details/132587534
比如:
初始時(shí)時(shí)基于約定的路由:
routes.MapRoute(name: "Default", template: "{controller=Home}/{action=Index}/{id?}");
Controller中基于屬性的路由:
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
}
}
Model 綁定
Model 綁定功能把客戶端的請(qǐng)求數(shù)據(jù)(表彰數(shù)據(jù),路由數(shù)據(jù),請(qǐng)求字符串,HTTP header)轉(zhuǎn)換成 controller可以接收的對(duì)象。這樣,controller 就不用分析請(qǐng)求數(shù)據(jù),直接把請(qǐng)求數(shù)據(jù)作為 Action 的入?yún)ⅰ?/p>
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ... }
Model 驗(yàn)證
使用Model 綁定功能后,可以在客戶端發(fā)送請(qǐng)求之前就驗(yàn)證請(qǐng)求數(shù)據(jù),以及在 Action 處理之前驗(yàn)證數(shù)據(jù)。
using System.ComponentModel.DataAnnotations;
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Action的代碼:
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
// work with the model
}
// At this point, something failed, redisplay form
return View(model);
}
.NET 會(huì)同時(shí)在客戶端和服務(wù)端進(jìn)行 Model 驗(yàn)證。
依賴注入
可以在 Controller 的構(gòu)造函數(shù)中注入依賴類,也可以在 View 中使用 @inject 指令注入:
@inject SomeService ServiceName
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ServiceName.GetTitle</title>
</head>
<body>
<h1>@ServiceName.GetTitle</h1>
</body>
</html>
篩選器 Filters
Filters 用于預(yù)處理或者后處理 pipeline 中的請(qǐng)求,比如異常處理,緩存,Authorization,日志。
比如:
Areas
Areas 用于分組功能。
MVC 架構(gòu)中,Model, Controller, 和 View 代碼放在不同的物理文件夾中。
而在大型 App 中,還需要把每個(gè)Controller/Model/View模塊按功能放在不同的子分組中。
強(qiáng)類型的 View
Controllers 可以向 View 返回一個(gè)強(qiáng)類型 Model 的 View。
比如這個(gè)類型為IEnumerable的 View。
@model IEnumerable<Product>
<ul>
@foreach (Product p in Model)
{
<li>@p.Name</li>
}
</ul>
Tag Helpers
Tag Helpers 用于 server 端生成 HTML。
Tag Helpers 可以自定義 HTML元素或者修改現(xiàn)有 HTML 元素。
Tag Helpers 綁定到 HTML元素的屬性上。
Tag Helpers 有原生支持和第三方開發(fā)的。
比如:LinkTagHelper 可以用于創(chuàng)建指向AccountsController.Login 的鏈接。
<p>
Thank you for confirming your email.
Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>
比如:EnvironmentTagHelper 可以用于根據(jù)環(huán)境使用不同的 HTML:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-697751.html
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.js"
asp-fallback-src="~/lib/jquery/dist/jquery.js"
asp-fallback-test="window.jQuery">
</script>
</environment>
內(nèi)置的Tag Helpers
- asp-controller 和asp-action,生成 URL,比如:
<a asp-controller="Speaker"
asp-action="Evaluations">Speaker Evaluations</a>
生成:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-697751.html
<a href="/Speaker/Evaluations">Speaker Evaluations</a>
- asp-route,asp-all-route-data,asp-route-{value},asp-area,匹配路由
- asp-fragment,生成 html 錨點(diǎn)
- asp-protocol,指定 http 協(xié)議,比如 https
- asp-host,指定 url 的主機(jī)名
- asp-page,生成 hrel 的超鏈接
- cache,distributed-cache,緩存數(shù)據(jù)
- environment,根據(jù)環(huán)境使用不同的 HTML
- form,生成表單
- formaction,提前表單
- input,
- label
- select
- textarea
- asp-validation-for
- asp-validation-summary
- img,加強(qiáng)img標(biāo)簽。
- Link 類
- href
- asp-fallback-href
- partial,partial view
- script
到了這里,關(guān)于ASP.NET Core 中的 MVC架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!