asp.net core系列 41 Web 應用 MVC視圖
一.MVC視圖
在Web開發的MVC和Razor中,都有使用視圖,在Razor中稱為"頁"。.cshtml視圖是嵌入了Razor標記的HTML模板。 Razor 標記使用C#代碼,用於與HTML 標記交互以生成發送給客戶端的網頁。在MVC目錄結構中,Views / [ControllerName] 文件夾下用於創建視圖,其中Views/Shared 文件夾下的視圖是控制器共享的視圖。
1.1 視圖頁Razor 標記
下面是Views/Home 文件夾中創建一個 About.cshtml 文件,呈現的視圖如下:
@{ ViewData["Title"] = "About"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3>
Razor 標記以 @ 符號開頭。後面的大括號 { ... } 括住的是 Razor 代碼塊,是運行 C# 語句。 只需用 @
符號來引用值,即可在 HTML 中顯示這些值。比如上面h2和h3標簽。
1.2 控制器指定視圖
通常以 ViewResult 的形式從Action返回結果到視圖,這是一種 ActionResult結果類型(Web api中有講到)。但通常不會這樣做。 因為大多數控制器均繼承自Controller,因此只需使用 View 方法即可返回 ViewResult。示例如下:
public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); }
View
方法有多個重載。 可選擇指定:
//要返回的顯式視圖 return View("Orders"); //要傳遞給視圖的模型(實體)對象 return View(Orders); //視圖和模型 return View("Orders", Orders);
1.3 視圖發現
Action返回一個視圖時, 這個過程叫“視圖發現”。默認的 return View();
將返回與當前Action方法同名的視圖。搜索匹配的視圖文件順序規則如下:
Views/[ControllerName]/[ViewName].cshtml Views/Shared/[ViewName].cshtml
當return View()
時,首先在 Views/[ControllerName] 文件夾中搜索該視圖。 如果在此處找不到匹配的視圖,則會在“Shared”文件夾中搜索該視圖。
在返回視圖時,可以提供視圖文件路徑。 如果使用絕對路徑(“/”或“~/”開頭),必須指定 .cshtml 擴展名:
return View("Views/Home/About.cshtml");
也可使用相對路徑在不同目錄中指定視圖,而無需指定 .cshtml 擴展名:
return View("../Manage/Index");
可以用“./”前綴來指示當前的控制器特定目錄:
return View("./About");
1.4 向視圖傳遞數據
可以使用多種方法將數據傳遞給視圖。包括:(1)強類型數據:viewmodel。(2)弱類型數據ViewData (ViewDataAttribute)、ViewBag。ViewBag
在 Razor 頁中不可用。
(1) 強類型數據 viewmodel
在傳遞數據到視圖中,最可靠的是使用強類型數據,因為編譯時能檢查並且有智能感知。在視圖頁中使用@model指令來指定模型(可以是實體或集合泛型實體)。如下所示,其中前端的WebApplication1.ViewModels.Address是實體類命令空間,通過後端返回view強類型映射:
@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>
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); }
(2) 弱類型數據(ViewData、ViewData 屬性和 ViewBag)
視圖還可以訪問弱類型(也稱為松散類型)的數據集合。可以使用弱類型數據集合將少量數據傳入及傳出控制器和視圖。ViewData
屬性是弱類型對象的字典。ViewBag
屬性是 ViewData
的包裝器,為基礎 ViewData
集合提供動態屬性。ViewData派生自 ViewDataDictionary,ViewBag派生自 DynamicViewData。
ViewData
和 ViewBag
在運行時進行動態解析。 由於它們不提供編譯時類型檢查,因此使用這兩者通常比使用 viewmodel 更容易出錯。建議盡量減少或根本不使用 ViewData
和 ViewBag
。
ViewData介紹
下面是一個ViewData存儲對象,在視圖上強制轉換為特定類型(Address)。
public IActionResult SomeAction() { ViewData["Greeting"] = "Hello"; ViewData["Address"] = new Address() { Name = "Steve", Street = "123 Main St", City = "Hudson", State = "OH", PostalCode = "44236" }; return View(); }
@{ // 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>
ViewData 特性介紹
可以在控制器或 Razor 頁面模型上,使用 [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(); } }
//通過字典key取出
<title>@ViewData["Title"] - WebApplication</title>
ViewBag介紹
ViewBag
不需要強制轉換,因此使用起來更加方便。下面示例如下:
public IActionResult SomeAction() { // Greeting不需要先聲明,Address 也一樣,因為是Dynamic類型 ViewBag.Greeting = "Hello"; ViewBag.Address = new Address() { Name = "Steve", Street = "123 Main St", City = "Hudson", State = "OH", PostalCode = "44236" }; return View(); }
@ViewBag.Greeting World! <address> @ViewBag.Address.Name<br> @ViewBag.Address.Street<br> @ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode </address>
更多視圖功能包括:標記幫助程序、服務註入視圖,視圖組件等
參考文獻
ASP.NET Core MVC 中的視圖
asp.net core系列 41 Web 應用 MVC視圖