3.3 视图 (View) 3.3 视图 (View) 在ASP.NET Core MVC中,视图(View)负责呈现应用程序的用户界面。它们是用户与应用程序交互的窗口,负责将模型数据转换为HTML或其他格式,并将其显示给用户。视图通常与控制器(Controller)密切配合,控制器负责处理用户请求、准备数据,并将数据传递给视图进行渲染。 3.3.1 视图的作用和重要性 呈现用户界面: 视图的主要职责是生成用户可见的HTML、CSS和JavaScript代码,构建应用程序的用户界面。 数据展示: 视图接收来自控制器的数据(模型),并将其以用户友好的方式呈现出来。 分离关注点: 通过将用户界面逻辑与业务逻辑分离,提高了代码的可维护性、可测试性和可重用性。
在ASP.NET Core MVC中,视图(View)负责呈现应用程序的用户界面。它们是用户与应用程序交互的窗口,负责将模型数据转换为HTML或其他格式,并将其显示给用户。视图通常与控制器(Controller)密切配合,控制器负责处理用户请求、准备数据,并将数据传递给视图进行渲染。
呈现用户界面: 视图的主要职责是生成用户可见的HTML、CSS和JavaScript代码,构建应用程序的用户界面。
数据展示: 视图接收来自控制器的数据(模型),并将其以用户友好的方式呈现出来。
分离关注点: 通过将用户界面逻辑与业务逻辑分离,提高了代码的可维护性、可测试性和可重用性。
灵活性: 视图允许我们针对不同的设备或用户角色创建不同的用户界面,而无需修改业务逻辑。
ASP.NET Core MVC 支持多种视图引擎,其中最常用的是 Razor 视图引擎。
Razor 视图: Razor 视图使用 .cshtml 扩展名,它允许我们在 HTML 代码中嵌入 C# 代码,从而动态生成用户界面。
其他视图引擎: ASP.NET Core MVC 也支持其他视图引擎,如 .aspx (Web Forms) 视图引擎,但 Razor 是推荐的选择,因为它更简洁、更强大。
Razor 视图使用 @ 符号来表示 C# 代码块。以下是一些常用的 Razor 语法:
显示表达式: @Model.PropertyName 用于显示模型对象的属性值。
代码块: @{ ... } 用于包含 C# 代码。
控制结构: @if, @else, @for, @foreach, @while 用于控制视图的渲染逻辑。
HTML 编码: Razor 默认会对输出进行 HTML 编码,以防止 XSS 攻击。可以使用 @Html.Raw() 方法来禁用 HTML 编码。
布局页: @Layout 用于指定视图的布局页。
示例:
@model MyWebApp.Models.Product @{ ViewData["Title"] = "Product Details"; Layout = "_Layout"; } <h1>@ViewData["Title"]</h1> <div> <h2>@Model.Name</h2> <p>Price: @Model.Price</p> <p>Description: @Model.Description</p> @if (Model.IsAvailable) { <p>Available!</p> } else { <p>Out of stock.</p> } </div>
当控制器返回一个视图时,ASP.NET Core MVC 会按照一定的规则查找视图文件。默认情况下,它会在以下位置查找:
Views/{ControllerName}/{ActionName}.cshtml
Views/Shared/{ActionName}.cshtml
Views/Shared/{ControllerName}.cshtml
例如,如果控制器名为 ProductController,操作方法名为 Details,则 ASP.NET Core MVC 会首先在 Views/Product/Details.cshtml 中查找视图,如果找不到,则在 Views/Shared/Details.cshtml 中查找,最后在 Views/Shared/Product.cshtml 中查找。
我们可以通过以下方式自定义视图的查找路径:
使用 ViewResult.ViewName 属性: 在控制器中,我们可以使用 ViewResult.ViewName 属性来指定视图的名称。例如,return View("MyView"); 将会查找 Views/{ControllerName}/MyView.cshtml 或 Views/Shared/MyView.cshtml。
使用绝对路径: 我们可以使用绝对路径来指定视图的位置。例如,return View("~/Views/MyFolder/MyView.cshtml");
控制器可以通过多种方式将数据传递给视图:
模型 (Model): 这是最常用的方式。控制器将一个对象作为模型传递给视图,视图可以通过 @model 指令访问该对象。
ViewBag: ViewBag 是一个动态对象,允许我们在控制器中设置属性,并在视图中访问这些属性。
ViewData: ViewData 是一个字典对象,允许我们在控制器中存储键值对,并在视图中访问这些键值对。
TempData: TempData 用于在重定向之间传递数据。它存储在 Cookie 或 Session 中,并在读取一次后被删除。
示例:
// 控制器 public IActionResult Details(int id) { var product = _productRepository.GetProductById(id); ViewBag.Message = "Welcome to the product details page!"; ViewData["Category"] = "Electronics"; return View(product); } // 视图 @model MyWebApp.Models.Product <h1>@ViewBag.Message</h1> <p>Category: @ViewData["Category"]</p> <h2>@Model.Name</h2>
布局页提供了一种在多个视图之间共享通用 HTML 结构的方式。它们通常包含页眉、页脚、导航栏等元素。
_ViewStart.cshtml: 该文件位于 Views 目录下,用于指定应用程序的默认布局页。
_Layout.cshtml: 这是典型的布局页文件,它定义了 HTML 的基本结构,并使用 @RenderBody() 方法来渲染视图的内容。
@RenderSection(): 布局页可以使用 @RenderSection() 方法来定义可由视图填充的区域。
示例:
_Layout.cshtml
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - MyWebApp</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" /> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MyWebApp</a> </div> </nav> </header> <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2023 - MyWebApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @RenderSection("Scripts", required: false) </body> </html>
Details.cshtml
@model MyWebApp.Models.Product @{ ViewData["Title"] = "Product Details"; Layout = "_Layout"; // 指定布局页 } <h1>@ViewData["Title"]</h1> <div> <h2>@Model.Name</h2> <p>Price: @Model.Price</p> <p>Description: @Model.Description</p> </div> @section Scripts { <script> // Custom JavaScript for this view console.log("Product details page loaded!"); </script> }
视图组件是可重用的 UI 组件,类似于分部视图,但它们更强大,因为它们可以包含自己的业务逻辑。
创建视图组件: 创建一个继承自 ViewComponent 类的类,并实现 InvokeAsync 方法。
在视图中使用视图组件: 使用 @await Component.InvokeAsync("ComponentName", new { /* parameters */ }) 在视图中调用视图组件。
示例:
ShoppingCartSummary.cs
using Microsoft.AspNetCore.Mvc; using MyWebApp.Models; public class ShoppingCartSummary : ViewComponent { private readonly IShoppingCart _shoppingCart; public ShoppingCartSummary(IShoppingCart shoppingCart) { _shoppingCart = shoppingCart; } public async Task<IViewComponentResult> InvokeAsync() { var items = await _shoppingCart.GetShoppingCartItemsAsync(); _shoppingCart.ShoppingCartItems = items; var shoppingCartViewModel = new ShoppingCartViewModel { ShoppingCart = _shoppingCart, ShoppingCartTotal = _shoppingCart.GetShoppingCartTotal() }; return View(shoppingCartViewModel); } }
Default.cshtml (ShoppingCartSummary 视图)
@model ShoppingCartViewModel <div> Items in your cart: @Model.ShoppingCart.ShoppingCartItems.Count Total: @Model.ShoppingCartTotal </div>
在布局页中使用视图组件:
<div class="container"> @await Component.InvokeAsync("ShoppingCartSummary") </div>
分部视图是可重用的视图片段,可以嵌入到其他视图中。它们通常用于显示重复的内容,如表单字段、产品列表等。
创建分部视图: 创建一个 .cshtml 文件,并将其放置在 Views/Shared 目录下,或者在控制器的视图目录下。
在视图中使用分部视图: 使用 @Html.Partial() 或 @Html.RenderPartial() 方法在视图中渲染分部视图。
示例:
_ProductSummary.cshtml
@model MyWebApp.Models.Product <div class="card"> <div class="card-body"> <h5 class="card-title">@Model.Name</h5> <p class="card-text">@Model.Description</p> <p class="card-text">Price: @Model.Price</p> </div> </div>
在视图中使用分部视图:
@model IEnumerable<MyWebApp.Models.Product> @foreach (var product in Model) { @Html.Partial("_ProductSummary", product) }
图解说明:
Controller (控制器): 接收用户请求,处理业务逻辑,并将数据 (Model) 传递给 View。
Model (模型): 包含应用程序的数据。
View (视图): 使用 Model 中的数据生成用户界面。
User Interface (用户界面): 用户最终看到的内容。
Layout Page (布局页): 定义了应用程序的通用 HTML 结构,View 嵌入到 Layout Page 中。
Partial View (分部视图): 可重用的视图片段,View 可以包含多个 Partial View。
View Component (视图组件): 可重用的 UI 组件,可以包含自己的业务逻辑。
视图是ASP.NET Core MVC应用程序中至关重要的组成部分,负责呈现用户界面并展示数据。Razor视图引擎提供了强大的语法,使得我们可以轻松地在HTML代码中嵌入C#代码,从而动态生成用户界面。通过合理地使用布局页、分部视图和视图组件,我们可以构建可维护、可重用的用户界面。 理解视图的工作原理和各种类型,对于开发高质量的ASP.NET Core MVC应用程序至关重要。