4.3 Razor Pages 页面指令与 Razor 语法


文档摘要

4.3 Razor Pages 页面指令与 Razor 语法 第四章:ASP.NET Core Razor Pages 父章节领域 - 4.3 Razor Pages 页面指令与 Razor 语法详解 4.3.1 Razor Pages 页面指令 (Page Directives) 页面指令是 Razor 视图引擎的特殊指示,它们以 符号开头,用于配置 Razor 页面的行为和功能。指令必须位于 Razor 页面的顶部,在任何 HTML 或 C# 代码之前。 4.3.1.1 指令 指令是 Razor Page 的核心指令,它将 文件标识为一个 Razor Page,使其能够处理 HTTP 请求。每个 Razor Page 文件 必须 包含 指令,否则 ASP.

## 4.3 Razor Pages 页面指令与 Razor 语法 ## 第四章:ASP.NET Core Razor Pages 父章节领域 - 4.3 Razor Pages 页面指令与 Razor 语法详解 ### 4.3.1 Razor Pages 页面指令 (Page Directives) 页面指令是 Razor 视图引擎的特殊指示,它们以 `@` 符号开头,用于配置 Razor 页面的行为和功能。指令必须位于 Razor 页面的顶部,在任何 HTML 或 C# 代码之前。 **4.3.1.1 `@page` 指令** `@page` 指令是 Razor Page 的核心指令,它将 `.cshtml` 文件标识为一个 Razor Page,使其能够处理 HTTP 请求。每个 Razor Page 文件 **必须** 包含 `@page` 指令,否则 ASP.NET Core 运行时将无法将其识别为可执行的页面。 **代码实践:** ```cshtml @page @* 页面内容从这里开始 *@

欢迎来到 Razor Pages!

``` **内容详解:** * **标识 Razor Page:** `@page` 指令是告诉 ASP.NET Core 运行时,这个 `.cshtml` 文件是一个 Razor Page,应该被编译和处理以响应 HTTP 请求。 * **路由配置:** 默认情况下,`@page` 指令会将 Razor Page 关联到与其文件路径相对应的路由。例如,位于 `Pages/Index.cshtml` 的页面,默认路由为 `/Index` 或 `/` (如果它是 Index 页面)。 * **自定义路由:** `@page` 指令还可以指定自定义路由模板,允许你更灵活地控制页面的 URL。 ```cshtml @page "/custom-route"

自定义路由页面

``` 在这个例子中,该页面将通过 `/custom-route` URL 访问,而不是默认的文件路径路由。 **4.3.1.2 `@model` 指令** `@model` 指令用于指定 Razor Page 的 **页模型 (Page Model)** 类型。页模型是一个 C# 类,它为 Razor Page 提供数据和处理逻辑。通过 `@model` 指令,Razor Page 可以强类型地访问页模型中的属性和方法。 **代码实践:** 首先,创建一个简单的页模型类 `MyPageModel.cs`: ```csharp // Pages/MyPageModel.cshtml.cs using Microsoft.AspNetCore.Mvc.RazorPages; namespace MyWebApp.Pages { public class MyPageModel : PageModel { public string Message { get; set; } public void OnGet() { Message = "Hello from Page Model!"; } } } ``` 然后,在 Razor Page `MyPageModel.cshtml` 中使用 `@model` 指令: ```cshtml @page @model MyWebApp.Pages.MyPageModel

@Model.Message

``` **内容详解:** * **强类型页模型:** `@model MyWebApp.Pages.MyPageModel` 声明了当前 Razor Page 的页模型类型为 `MyWebApp.Pages.MyPageModel`。这意味着在 Razor 视图中,你可以通过 `Model` 属性访问 `MyPageModel` 类的实例。 * **数据绑定:** 页模型负责处理页面所需的数据。`@model` 指令使得 Razor Page 可以直接绑定到页模型的数据,并在视图中显示。 * **代码组织:** 使用页模型可以将页面的展示逻辑(Razor 视图)和业务逻辑(页模型类)清晰地分离,提高代码的可维护性和可测试性。 **4.3.1.3 `@using` 指令** `@using` 指令类似于 C# 中的 `using` 语句,用于在 Razor Page 中导入命名空间。这使得你可以直接使用命名空间中的类型,而无需写完整的命名空间前缀。 **代码实践:** ```cshtml @page @using System.Collections.Generic @{ List names = new List() { "Alice", "Bob", "Charlie" }; }
    @foreach(var name in names) {
  • @name
  • }
``` **内容详解:** * **简化代码:** `@using System.Collections.Generic` 导入了 `System.Collections.Generic` 命名空间,因此可以在 Razor Page 中直接使用 `List` 而不必写 `System.Collections.Generic.List`。 * **提高可读性:** 通过导入常用的命名空间,可以减少代码的冗余,提高 Razor Page 的可读性。 * **常用命名空间:** 在 Razor Pages 中,通常会使用 `@using` 指令导入 `System`、`System.Collections.Generic`、`System.Linq`、`Microsoft.AspNetCore.Mvc`、`Microsoft.AspNetCore.Mvc.RazorPages` 等常用命名空间。 **4.3.1.4 `@inject` 指令** `@inject` 指令用于在 Razor Page 中注入服务。ASP.NET Core 具有强大的依赖注入 (Dependency Injection, DI) 系统,`@inject` 指令允许你在 Razor 视图中直接访问已注册的服务。 **代码实践:** 首先,假设你已经注册了一个服务 `IMyService`: ```csharp // IMyService.cs public interface IMyService { string GetMessage(); } // MyService.cs public class MyService : IMyService { public string GetMessage() { return "Message from injected service!"; } } // Startup.cs (ConfigureServices 方法) public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddScoped(); // 注册服务 } ``` 然后,在 Razor Page 中使用 `@inject` 指令注入 `IMyService`: ```cshtml @page @inject IMyService MyService

@MyService.GetMessage()

``` **内容详解:** * **服务注入:** `@inject IMyService MyService` 指令将类型为 `IMyService` 的服务注入到 Razor Page,并将其命名为 `MyService` 变量。 * **访问服务方法:** 注入服务后,可以在 Razor 视图中直接调用服务的方法,例如 `@MyService.GetMessage()`。 * **解耦和可测试性:** 通过依赖注入,Razor Page 可以依赖于抽象的服务接口,而不是具体的实现,降低了组件之间的耦合度,并提高了代码的可测试性。 **4.3.1.5 `@layout` 指令** `@layout` 指令用于指定 Razor Page 使用的布局页 (Layout Page)。布局页是一个共享的 Razor 视图,用于定义网站的通用结构,例如页眉、页脚、导航栏等。 **代码实践:** 首先,创建一个布局页 `_Layout.cshtml` (通常位于 `Pages/Shared` 文件夹下): ```cshtml @* Pages/Shared/_Layout.cshtml *@ @ViewData["Title"]

网站标题

@RenderBody()

© @DateTime.Now.Year My Website

``` 然后,在 Razor Page 中使用 `@layout` 指令指定布局页: ```cshtml @page @layout "/Pages/Shared/_Layout.cshtml" @{ ViewData["Title"] = "首页"; }

欢迎来到首页

这是首页的内容。

``` **内容详解:** * **共享布局:** `@layout "/Pages/Shared/_Layout.cshtml"` 指令指定当前 Razor Page 使用 `/Pages/Shared/_Layout.cshtml` 作为布局页。这意味着当前页面的内容将被渲染到布局页的 `@RenderBody()` 方法所在的位置。 * **统一外观:** 使用布局页可以确保网站的所有页面具有一致的外观和结构,提高用户体验和维护效率。 * **`@RenderBody()`:** 布局页中的 `@RenderBody()` 方法是占位符,用于渲染使用该布局页的 Razor Page 的内容。 * **`ViewData["Title"]`:** 可以通过 `ViewData` 字典向布局页传递数据,例如设置页面的标题。 **4.3.1.6 `@section` 指令** `@section` 指令用于在 Razor Page 中定义 **节 (Section)**。节允许你在布局页中预留一些区域,然后在不同的 Razor Page 中填充这些区域的内容。 **代码实践:** 在布局页 `_Layout.cshtml` 中定义一个节 `@RenderSection()`: ```cshtml @* Pages/Shared/_Layout.cshtml *@ @ViewData["Title"] @RenderSection("Scripts", required: false)

网站标题

@RenderBody()

© @DateTime.Now.Year My Website

``` 在 Razor Page 中使用 `@section` 指令定义 `Scripts` 节的内容: ```cshtml @page @layout "/Pages/Shared/_Layout.cshtml" @{ ViewData["Title"] = "带节的页面"; }

带节的页面

这是带节的页面内容。

@section Scripts { } ``` **内容详解:** * **定义节内容:** `@section Scripts { ... }` 指令在 Razor Page 中定义了一个名为 `Scripts` 的节,其中的代码将被渲染到布局页中 `RenderSection("Scripts", ...)` 方法所在的位置。 * **可选节:** `RenderSection("Scripts", required: false)` 中的 `required: false` 参数表示 `Scripts` 节是可选的。如果 Razor Page 没有定义 `Scripts` 节,布局页不会报错。如果设置为 `required: true`,则 Razor Page 必须定义该节。 * **组织页面结构:** 节允许更灵活地组织页面结构,例如将特定的 JavaScript 代码或 CSS 样式放在页面的特定位置。 **4.3.1.7 `@namespace` 指令** `@namespace` 指令用于为 Razor Page 生成的 C# 类指定命名空间。默认情况下,Razor Page 的命名空间会根据其文件路径自动生成。`@namespace` 指令允许你覆盖默认的命名空间。 **代码实践:** ```cshtml @page @namespace MyWebApp.CustomPages

自定义命名空间页面

``` **内容详解:** * **自定义命名空间:** `@namespace MyWebApp.CustomPages` 指令将当前 Razor Page 生成的 C# 类的命名空间设置为 `MyWebApp.CustomPages`。 * **代码组织:** 使用 `@namespace` 指令可以更好地组织 Razor Pages 的代码结构,使其更符合项目的命名规范。 * **默认命名空间:** 如果 Razor Page 没有使用 `@namespace` 指令,其默认命名空间通常会基于 Pages 文件夹的结构生成,例如 `MyWebApp.Pages.SubFolder`。 **4.3.1.8 `@functions` 和 `@code` 指令** `@functions` 和 `@code` 指令用于在 Razor Page 中定义 C# 代码块。`@functions` 用于定义 Razor Page 的成员(例如方法、属性),而 `@code` 通常用于定义局部变量和辅助方法。在 Razor Pages 中,更推荐使用页模型 (Page Model) 来处理逻辑,而不是在 Razor 视图中编写大量代码,但这两个指令在某些简单场景下仍然很有用。 **代码实践:** ```cshtml @page @functions { public string GetGreeting(string name) { return $"Hello, {name}!"; } } @{ string userName = "John"; string greetingMessage = GetGreeting(userName); }

@greetingMessage

``` **内容详解:** * **`@functions`:** `@functions { ... }` 块用于定义 Razor Page 的成员。在上面的例子中,定义了一个 `GetGreeting` 方法。 * **`@code`:** `@code { ... }` 块 (在 Razor Pages 中 `@code` 和 `@functions` 行为基本相同,推荐使用 `@functions` 保持一致性) 用于编写 C# 代码,例如声明变量、执行逻辑等。 * **代码内联:** 这两个指令允许在 Razor 视图中嵌入 C# 代码,但应谨慎使用,避免过度复杂的逻辑放在视图中。 **4.3.1.9 Tag Helper 指令 (`@addTagHelper`, `@removeTagHelper`, `@tagHelperPrefix`)** Tag Helpers 是 ASP.NET Core 中用于在 Razor 视图中渲染服务器端代码的强大机制。以下指令用于管理 Tag Helpers: * **`@addTagHelper`:** 添加 Tag Helpers 到 Razor Page。 * **`@removeTagHelper`:** 移除 Tag Helpers 从 Razor Page。 * **`@tagHelperPrefix`:** 为 Tag Helpers 设置前缀。 **代码实践:** ```cshtml @page @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @* 添加所有 Microsoft.AspNetCore.Mvc.TagHelpers 中的 Tag Helpers *@ 提交 @* 使用内置的 FormTagHelper *@ ``` **内容详解:** * **`@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers`:** 这个指令添加了 `Microsoft.AspNetCore.Mvc.TagHelpers` 程序集中的 **所有** Tag Helpers (`*` 通配符表示所有 Tag Helpers)。 * **Tag Helper 使用:** `提交` 使用了 `FormTagHelper` 的 `asp-page-handler` 属性,该属性将按钮与 Razor Page 的 `OnPostSubmit` 或 `OnGetSubmit` 处理程序方法关联起来。 * **Tag Helper 管理:** `@removeTagHelper` 可以用于移除特定的 Tag Helpers 或程序集中的 Tag Helpers。`@tagHelperPrefix` 可以为 Tag Helpers 设置一个自定义前缀,以避免与 HTML 标签冲突。 **4.3.1.10 其他指令 (`@attribute`, `@implements`, `@inherits`, `@typeparam`)** * **`@attribute`:** 向生成的 Razor Page 类添加属性。 * **`@implements`:** 使 Razor Page 类实现接口。 * **`@inherits`:** 使 Razor Page 类继承自指定的基类。 * **`@typeparam`:** 为 Razor Page 定义泛型类型参数。 这些指令相对高级,在 Razor Pages 中较少使用,通常用于更复杂的场景或自定义组件开发。 它们允许更底层的控制 Razor Page 类的生成过程。 ### 4.3.2 Razor 语法 (Razor Syntax) Razor 语法是 Razor 视图引擎的核心,它允许你在 HTML 中嵌入 C# 代码,从而实现动态内容渲染。Razor 语法以 `@` 符号开头,并提供了多种结构来编写 C# 代码。 **4.3.2.1 代码块 (`@{ ... }`)** 代码块使用 `@{ ... }` 语法,允许你在 Razor 视图中编写多行 C# 代码。代码块中的代码在服务器端执行,其结果不会直接输出到 HTML 中,除非显式地使用输出语法。 **代码实践:** ```cshtml @page @{ string message = "Hello Razor!"; int currentYear = DateTime.Now.Year; }

@message

当前年份: @currentYear

``` **内容详解:** * **服务器端代码:** `@{ ... }` 块中的 C# 代码在服务器端执行。 * **变量声明和逻辑:** 可以在代码块中声明变量、执行逻辑、调用方法等。 * **不直接输出:** 代码块中的代码不会直接输出到 HTML,需要使用 Razor 的输出语法 (例如 `@variable`) 将结果输出到 HTML 中。 **4.3.2.2 隐式表达式 (`@variable` 或 `@Model.Property`)** 隐式表达式使用 `@` 符号后跟 C# 变量、属性或简单的表达式。Razor 引擎会自动解析表达式的值,并将其输出到 HTML 中。 **代码实践:** ```cshtml @page @model string

@Model

@* 输出页模型的值 *@

当前时间: @DateTime.Now

@* 输出 DateTime.Now 的值 *@ ``` **内容详解:** * **简洁输出:** 隐式表达式是输出 C# 变量或属性值的最简洁方式。 * **自动 HTML 编码:** Razor 引擎默认会对隐式表达式的输出进行 HTML 编码,以防止跨站脚本攻击 (XSS)。例如,如果表达式的值包含 ` } ``` **内容总结:** * **`@page "/example"`:** 自定义路由为 `/example`。 * **`@namespace MyWebApp.ExamplePages`:** 自定义命名空间。 * **`@model MyWebApp.Pages.MyExamplePageModel`:** 指定页模型。 * **`@using System.DateTime`:** 导入 `System.DateTime` 命名空间。 * **`@layout "/Pages/Shared/_Layout.cshtml"`:** 使用布局页。 * **`ViewData["Title"] = Model.PageTitle;`:** 设置页面标题。 * **`@if (Model.ShowMessage) { ... }`:** 条件渲染。 * **`@foreach (var item in Model.Items) { ... }`:** 循环渲染列表。 * **`@userName.ToUpper()`:** 显式表达式,调用方法。 * **`@DateTime.Now`:** 隐式表达式,输出当前时间。 * **`@section Scripts { ... }`:** 定义 `Scripts` 节。 通过学习和实践本章节的内容,你应该对 Razor Pages 的页面指令和 Razor 语法有了深入的理解。掌握这些核心概念,你就能构建出更强大、更灵活的 ASP.NET Core Razor Pages 应用。在后续的章节中,我们将继续深入探索 Razor Pages 的更多高级特性和开发技巧。

发布者: 作者: 转发
评论区 (0)
U