1. 什麼是Mvc 模型-視圖-控制器 (MVC) 體繫結構模式將應用程式分成 3 個主要組件組:視圖模型、視圖和控制器。 此模式有助於實現關註點分離。 使用此模式,用戶請求被路由到控制器,後者負責使用模型來執行用戶操作和/或檢索查詢結果。 控制器選擇要顯示給用戶的視圖,併為其提供所需的任何模型數據 ...
模型-視圖-控制器 (MVC) 體繫結構模式將應用程式分成 3 個主要組件組:視圖模型、視圖和控制器。 此模式有助於實現
下圖顯示 3 個主要組件及其相互引用關係:
這種責任劃分有助於根據複雜性縮放應用程式,因為這更易於編碼、調試和測試包含單一作業的某個組成部分(模型、視圖或控制器)。 但這會加大更新、測試和調試代碼的難度,該代碼在這 3 個領域的兩個或多個領域間存在依賴關係。 例如,用戶界面邏輯的變更頻率往往高於業務邏輯。 如果將表示代碼和業務邏輯組合在單個對象中,則每次更改用戶界面時都必須修改包含業務邏輯的對象。 這常常會引發錯誤,並且需要在每次進行細微的用戶界面更改後重新測試業務邏輯。
視圖和控制器均依賴於模型。 但是,模型既不依賴於視圖,也不依賴於控制器。 這是分離的一個關鍵優勢。 這種分離允許模型獨立於可視化展示進行構建和測試。
模型責任
MVC 應用程式的模型 (M) 表示應用程式和任何應由其執行的業務邏輯或操作的狀態。 業務邏輯應與保持應用程式狀態的任何實現邏輯一起封裝在模型中。 強類型視圖通常使用 ViewModel 類型,旨在包含要在該視圖上顯示的數據。 控制器從模型創建並填充 ViewModel 實例。
視圖責任
視圖 (V) 負責通過用戶界面展示內容。 它們使用
控制器職責
控制器 (C) 是處理用戶交互、使用模型並最終選擇要呈現的視圖的組件。 在 MVC 應用程式中,視圖僅顯示信息;控制器處理並響應用戶輸入和交互。 在 MVC 模式中,控制器是初始入口點,負責選擇要使用的模型類型和要呈現的視圖(因此得名 - 它控制應用如何響應給定請求)。
備註
控制器不應由於責任過多而變得過於複雜。 要阻止控制器邏輯變得過於複雜,請將業務邏輯推出控制器並推入域模型。
提示
如果發現控制器操作經常執行相同類型的操作,可將這些常見操作移入
2. ASP.NET Core MVC
ASP.NET Core MVC 框架是輕量級、開源、高度可測試的演示框架,並針對 ASP.NET Core 進行了優化。它摒棄了傳統的全家桶模式,採用了按需所取的方式給用戶提供服務。
ASP.NET Core MVC 提供一種基於模式的方式,用於生成可徹底分開管理事務的動態網站。 它提供對標記的完全控制,支持 TDD 友好開發並使用最新的 Web 標準。
1. 與Framework 下的 Asp.Net Mvc 的區別
詳細內容:
差異 | Frameowrk Mvc | Mvc Core |
---|---|---|
體繫結構 | 非跨平臺 | 跨平臺 |
啟動方式 | ASP.NET 應用托管在 IIS 中,它們依賴於 IIS 來實例化某些對象,併在請求到達時調用某些方法。 | ASP.NET Core 應用是獨立程式。 因此,它們通常包含一個 Program.cs 文件,該文件包含應用的入口點 . |
托管差異 | ASP.NET MVC 應用托管在 IIS 中,並可能依賴 IIS 配置來實現其行為。 這通常包括 | 使用了更輕量的kestrel 伺服器,它可支持跨平臺 |
靜態文件 | 由 IIS 托管靜態文件。支持將靜態文件與應在伺服器上保持私有的文件併排放置。(可使用內容分髮網絡CDN優化) | 不能直接支持,必須配置 |
註入差異 | 需要藉助第三方工具,如Autofac,Unity,Ninject... | 內置於框架中,在應用啟動時,將調用 ConfigureServices ,該調用負責註冊 DI 容器(服務集合/服務提供商)可在應用中創建和註入的所有類型 |
模塊和處理程式 | ASP.NET Core 在每個應用的 Configure 方法中定義一個請求管道。 此請求管道定義了應用如何處理傳入的請求,其中管道中的每個方法都調用下一個方法,直到最終方法終止(按需所用) |
|
配置差異 | 配置使用應用文件夾中內置的 .NET 配置文件web.config,ConfigurationManager靜態訪問 | 配置本身是可配置的。可根據需要註入 |
2. Mvc:約定大於配置
-
控制器類加Controller尾碼,而且都放在Web項目下的Controllers文件夾中,控制器類繼承Controller基類。
-
視圖文件必須放在名稱為Views/Pages 的文件夾下的名稱為控制器名稱的文件夾中。
-
_ViewStart.cshtml 執行任何Action(控制器中以IActionResult為返回類型的方法叫Action方法)之前,都會先執行它.
-
以下劃線命名開頭的視圖一般作為佈局/ViewCompenent 視圖,放在shared文件夾下麵
-
_ViewImport.cshtm 為全局視圖文件共公命名空間的引用
3. 快速入門
-
創建項目
剛新建好的空項目:
-
選中Controllers 文件夾,右鍵-->新建-->類/介面
-
控制器代碼
// Hello 表示控制器名稱,HelloController 是控制器類名(C) public class HelloController:Controller { // 創建視圖文件的方法(V) public IActionResult Index() { // 業務邏輯,模型操作(M) List<StudentViewModel> list = new List<StudentViewModel>() { new(1,"張三"), // C#9.0 以上創建對象語法 new(2,"李四"), new (3,"王五") }; return View(list);// 將模型數據傳遞給視圖 } } public record StudentViewModel(int Id,string Name);
-
在Views/ 目錄下創建Hello目錄,在Hello目錄下創建Index.cshtml文件。
-
編寫任意html代碼
@* 接收視圖模型傳遞過來的數據 *@ @model List<WebApplication2.Controllers.StudentViewModel> @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Mvc 快速入門</title> </head> <body> <div> <h1>大家好,歡迎來到任我行碼農場,Asp.net Mvc</h1> </div> </body> </html>
3. Mvc 項目結構
-
Dependencies:項目所依賴的組件
-
launchSettings.json : 項目發佈設置文件
{ "iisSettings": {// iis 設置 "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:21843", "sslPort": 44331 } }, "profiles": { "WebApplication2": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true,// 使用瀏覽器 "applicationUrl": "http://localhost:5096",// 項目運行地址 "environmentVariables": { // 當前環境 "ASPNETCORE_ENVIRONMENT": "Development" // 表示當前環境為Development } }, "IIS Express": { // 內置IIS 的設置 "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
-
Controllers: 存放所有的控制器
-
Models: 存放所有的ViewModel 文件
-
Views: 存放所有的視圖文件
-
Views/Shared : 存放公共的視圖文件
-
Views/Shared/_Layout.cshtml : 公共佈局文件
-
Views/Shared/Error.cshtml: 錯誤提示視圖
-
Views/_ViewImports.cshtml: 公共導入命名空間,引用公共的標簽助手
@using WebApplication2 @using WebApplication2.Models @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Views/_ViewStart.cshtml: 視圖起始文件,所有視圖在載入時,都會先載入此視圖文件 wwwroot: 存放所有的靜態資源文件(css/js/html) wwwroot/favicon.ico : 應用程式的圖標 appsetting.json: 當前應用程式的配置文件 appsetting.Development.json: 當前環境的配置文件,如果在此文件中未找到想要的配置,則會去appsetting.json 文件中去尋找。 Program:程式的主入口,用於初始化系統的相關配置,註冊服務,配置中間件與註冊管道。 4. 控制器動作 控制器動作(具體的action)返回的結果叫做控制器動作結果,動作結果是控制器返回給瀏覽器請求的內容。ASP.NET Core MVC 框架支持幾十種標準類型的動作結果,以下是常見的類型 動作名稱 簡要概述 ViewResult 返回視圖 RedirectToActionResult 重定向到某個Action方法 JsonResult Json結果,可以用於Ajax應用程式 ContentResult 文本結果 RedirectResult 重定向到一個新的URL FileResult 返回一個文件,一般用於下載 它們 都實現了IActionResult 介面。 public ViewResult Index() { List<StudentViewModel> list = new List<StudentViewModel>() { new(1,"張三"), new(2,"李四"), new (3,"王五") }; return View(list); } public JsonResult Index2() { List<StudentViewModel> list = new List<StudentViewModel>() { new(1,"張三"), new(2,"李四"), new (3,"王五") }; return Json(list); } public ContentResult Index3() { return Content("hello,任我行碼農場"); } public RedirectToActionResult Index4() { return RedirectToAction("Index2", "Hello"); } public FileResult Download() { using MemoryStream ms = new MemoryStream(); var buffer = Encoding.UTF8.GetBytes("文件下載"); ms.Write(buffer); return File(ms.ToArray(), "application/octet-stream", "測試文件.txt"); }
Action方法與普通方法的區別
Action方法是由Mvc 框架管理,Mvc 框架可以對Action方法進行處理與渲染(例如渲染視圖,攔截請求等等),而普通則不受mvc 控制。
舉個例子,ContentResult 通常的作用也是直接返回一個字元串,當我們執行Content("hello,任我行碼農場")
時,我們只是告訴Mvc框架,我們需要返回 “hello,任我行碼農場”
,而並非立即返回,Mvc 框架在此之後可能還會做很多的處理,或許在中間的某個環節,有可能請求被攔截,導致我們可能得到不同的結果(日後要講的AOPA思想)。而return "hello,任我行碼農場"
則是立即返回。
5. Razor視圖
註釋
@* *@
輸出純文本:
@:這裡是妹子可以看的內容
編寫C#代碼
<html> <head> <title>Mvc 快速入門</title> </head> <body> <div> <h1>大家好,歡迎來到任我行碼農場,Asp.net Mvc</h1> @{ int a = 1; int b = 2; Console.WriteLine(a+b); } </div> </body> </html>
if else
<html> <head> <title>Mvc 快速入門</title> </head> <body> <div> <h1>大家好,歡迎來到任我行碼農場,Asp.net Mvc</h1> @if (true) { <h1>hello</h1> } else { <p>world</p> } </div> </body> </html>
視圖傳值
1. TempData
public IActionResult Index() { TempData["username"] = "任我行"; return View(); } <body> <div> <h1>我的名稱:@TempData["username"]</h1> </div> </body>
TempData 保存在Session中,Controller每次執行請求的時候,會從Session中先獲取 TempData,而後清除Session,獲取完TempData數據,雖然保存在內部字典對象中,但是其集合中的每個條目訪問一次後就從字典表中刪 除。具體代碼層面,TempData獲取過程是通過SessionStateTempDataProvider.LoadTempData方法從 ControllerContext的Session中讀取數據,而後清除Session,故TempData只能跨Controller傳遞一次。
2.ViewBag 與 ViewData
ViewData:
ViewData 只在當前 Action 中有效,
public IActionResult Index() { ViewData["username"] = "任我行"; return View(); } <body> <div> <h1>我的名稱:@ViewData["username"]</h1> </div> </body>
ViewBag
ViewBag其實本質就是ViewData,只是多了層Dynamic控制。所以,使用何種方式完全取決於你的個人愛好。
public IActionResult Index() { ViewBag.UserName = "任我行"; return View(); } <body> <div> <h1>我的名稱:@ViewBag.UserName</h1> </div> </body>
兩者區別如下:
ViewData | ViewBag |
---|---|
它是key/value字典集合 | 它是dynamic類型對象 |
從asp.net mvc1就有了 | 從asp.netmvc3才有 |
基於asp.netframework 3.5 | 基於asp.net framework4.0 |
viewdata比viewbag快 | viewbag比viewdata慢 |
頁面查詢數據時需要轉換合適的類型 | 在頁面查詢數據時不需要轉換合適的類型 |
有一些類型轉換代碼 | 可讀性較好 |
總結
1、ViewData和TempData是字典類型,賦值方式用字典方式,ViewData["myName"]
2、ViewBag是動態類型,使用時直接添加屬性賦值即可 ViewBag.myName
3、ViewBag和ViewData只在當前Action中有效,等同於View
4、TempData可以通過轉向繼續使用(Server.Tranfer()),因為它的值保存在Session中。但TempData只能經過一次傳遞,之後會被系統自動清除(Framework)
5、ViewData和ViewBag中的值可以互相訪問,因為ViewBag的實現中包含了ViewData
配套視頻鏈接:什麼是Mvc (cctalk.com)海闊平魚躍,天高任我行,給我一片藍天,讓我自由翱翔。