ASP.NET Core 中的 Razor 页面介绍

Razor 页面是 ASP.NET Core MVC 的一个新功能,它可以使基于页面的编码方式更简单高效。

若要查找使用模型视图控制器方法的教程,请参阅 ASP.NET Core MVC 入门

本文档介绍 Razor 页面。 它并不是分步教程。 如果认为某些部分过于复杂,请参阅 Razor 页面入门 。 有关 ASP.NET Core 的概述,请参阅 ASP.NET Core 简介

Install one of the following:

  • CLI tooling: Windows, Linux, or macOS: .NET Core SDK 2.0 or later
  • IDE/editor tooling
  • Windows: Visual Studio for Windows ASP.NET and web development workload
  • .NET Core cross-platform development workload
  • Linux: Visual Studio Code
  • macOS: Visual Studio for Mac

    Visual Studio for Mac
    在命令行中运行 dotnet new razor
    在 Visual Studio for Mac 中打开生成的 .csproj 文件。

    Visual Studio Code
    在命令行中运行 dotnet new razor

    .NET Core CLI
    在命令行中运行 dotnet new razor

    Razor 页面

    Startup.cs 中已启用 Razor 页面:

    public class Startup
        public void ConfigureServices(IServiceCollection services)
            // Includes support for Razor Pages and controllers.
            services.AddMvc();
        public void Configure(IApplicationBuilder app)
            app.UseMvc();
    

    请考虑一个基本页面:

    @page
    <h1>Hello, world!</h1>
    <h2>The time on the server is @DateTime.Now</h2>
    

    上述代码看上去类似于一个 Razor 视图文件。 不同之处在于 @page 指令。 @page 使文件转换为一个 MVC 操作 ,这意味着它将直接处理请求,而无需通过控制器处理。 @page 必须是页面上的第一个 Razor 指令。 @page 将影响其他 Razor 构造的行为。

    将在以下两个文件中显示使用 PageModel 类的类似页面。 Pages/Index2.cshtml 文件:

    @page
    @using RazorPagesIntro.Pages
    @model IndexModel2
    <h2>Separate page model</h2>
        @Model.Message
    

    Pages/Index2.cshtml.cs 页面模型:

    using Microsoft.AspNetCore.Mvc.RazorPages;
    using System;
    namespace RazorPagesIntro.Pages
        public class IndexModel2 : PageModel
            public string Message { get; private set; } = "PageModel in C#";
            public void OnGet()
                Message += $" Server time is { DateTime.Now }";
    

    按照惯例,PageModel 类文件的名称与追加 .cs 的 Razor 页面文件名称相同。 例如,前面的 Razor 页面的名称为 Pages/Index2.cshtml。 包含 PageModel 类的文件的名称为 Pages/Index2.cshtml.cs。

    页面的 URL 路径的关联由页面在文件系统中的位置决定。 下表显示了 Razor 页面路径及匹配的 URL:

    文件名和路径 匹配的 URL

    编写基本窗体

    Razor 页面功能旨在简化 Web 浏览器常用的模式。 模型绑定标记帮助程序和 HTML 帮助程序均只可用于 Razor 页面类中定义的属性。 请参考为 Contact 模型实现基本的“联系我们”窗体的页面:

    在本文档中的示例中,DbContextStartup.cs 文件中进行初始化。

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.DependencyInjection;
    using RazorPagesContacts.Data;
    namespace RazorPagesContacts
        public class Startup
            public IHostingEnvironment HostingEnvironment { get; }
            public void ConfigureServices(IServiceCollection services)
                services.AddDbContext<AppDbContext>(options =>
                                  options.UseInMemoryDatabase("name"));
                services.AddMvc();
            public void Configure(IApplicationBuilder app)
                app.UseMvc();
    

    数据模型:

    using System.ComponentModel.DataAnnotations;
    namespace RazorPagesContacts.Data
        public class Customer
            public int Id { get; set; }
            [Required, StringLength(100)]
            public string Name { get; set; }
    

    数据库上下文:

    using Microsoft.EntityFrameworkCore;
    namespace RazorPagesContacts.Data
        public class AppDbContext : DbContext
            public AppDbContext(DbContextOptions options)
                : base(options)
            public DbSet<Customer> Customers { get; set; }
    

    Pages/Create.cshtml 视图文件:

    @page
    @model RazorPagesContacts.Pages.CreateModel
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
            Enter your name.
        <div asp-validation-summary="All"></div>
        <form method="POST">
            <div>Name: <input asp-for="Customer.Name" /></div>
            <input type="submit" />
        </form>
    </body>
    </html>
    

    Pages/Create.cshtml.cs 页面模型:

    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using RazorPagesContacts.Data;
    namespace RazorPagesContacts.Pages
        public class CreateModel : PageModel
            private readonly AppDbContext _db;
            public CreateModel(AppDbContext db)
                _db = db;
            [BindProperty]
            public Customer Customer { get; set; }
            public async Task<IActionResult> OnPostAsync()
                if (!ModelState.IsValid)
                    return Page();
                _db.Customers.Add(Customer);
                await _db.SaveChangesAsync();
                return RedirectToPage("/Index");
    

    按照惯例,PageModel 类命名为 <PageName>Model 并且它与页面位于同一个命名空间中。

    使用 PageModel 类,可以将页面的逻辑与其展示分离开来。 它定义了页面处理程序,用于处理发送到页面的请求和用于呈现页面的数据。 借助这种分离,可以通过依赖关系注入管理页面依赖关系,并对页面执行单元测试

    页面包含 OnPostAsync 处理程序方法,它在 POST 请求上运行(当用户发布窗体时)。 可以为任何 HTTP 谓词添加处理程序方法。 最常见的处理程序是:

    OnGet,用于初始化页面所需的状态。 OnGet 示例。

  • OnPost ,用于处理窗体提交。

    Async 命名后缀为可选,但是按照惯例通常会将它用于异步函数。 前面示例中的 OnPostAsync 代码看上去与通常在控制器中编写的内容相似。 前面的代码通常用于 Razor 页面。 多数 MVC 基元(例如 模型绑定 验证 和操作结果)都是共享的。

    之前的 OnPostAsync 方法:

    public async Task<IActionResult> OnPostAsync()
        if (!ModelState.IsValid)
            return Page();
        _db.Customers.Add(Customer);
        await _db.SaveChangesAsync();
        return RedirectToPage("/Index");
    

    OnPostAsync 的基本流:

    检查验证错误。

  • 如果没有错误,则保存数据并重定向。
  • 如果有错误,则再次显示页面并附带验证消息。 客户端验证与传统的 ASP.NET Core MVC 应用程序相同。 很多情况下,都会在客户端上检测到验证错误,并且从不将它们提交到服务器。
  • 成功输入数据后,OnPostAsync 处理程序方法调用 RedirectToPage 帮助程序方法来返回 RedirectToPageResult 的实例。 RedirectToPage 是新的操作结果,类似于 RedirectToActionRedirectToRoute,但是已针对页面进行自定义。 在前面的示例中,它将重定向到根索引页 (/Index)。 页面 URL 生成部分中详细介绍了 RedirectToPage

    提交的窗体存在(已传递到服务器的)验证错误时,OnPostAsync 处理程序方法调用 Page 帮助程序方法。Page 返回 PageResult 的实例。 返回 Page 的过程与控制器中的操作返回 View 的过程相似。PageResult 是处理程序方法的默认 返回类型。 返回 void 的处理程序方法将显示页面。

    Customer 属性使用 [BindProperty] 特性来选择加入模型绑定。

    public class CreateModel : PageModel
        private readonly AppDbContext _db;
        public CreateModel(AppDbContext db)
            _db = db;
        [BindProperty]
        public Customer Customer { get; set; }
        public async Task<IActionResult> OnPostAsync()
            if (!ModelState.IsValid)
                return Page();
            _db.Customers.Add(Customer);
            await _db.SaveChangesAsync();
            return RedirectToPage("/Index");
    

    默认情况下,Razor 页面只绑定带有非 GET 谓词的属性。 绑定属性可以减少需要编写的代码量。 绑定通过使用相同的属性显示窗体字段 (<input asp-for="Customer.Name" />) 来减少代码,并接受输入。

    出于安全原因,必须选择绑定 GET 请求数据以对模型属性进行分页。 请在将用户输入映射到属性前对其进行验证。 当构建依赖查询字符串或路由值的功能时,选择加入此行为非常有用。
    若要将属性绑定在 GET 请求上,请将 [BindProperty] 特性的 SupportsGet 属性设置为 true[BindProperty(SupportsGet = true)]

    主页 (Index.cshtml):

    @page
    @model RazorPagesContacts.Pages.IndexModel
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    <h1>Contacts</h1>
    <form method="post">
        <table class="table">
            <thead>
                    <th>ID</th>
                    <th>Name</th>
            </thead>
            <tbody>
                @foreach (var contact in Model.Customers)
                        <td>@contact.Id</td>
                        <td>@contact.Name</td>
                            <a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
                            <button type="submit" asp-page-handler="delete" 
                                    asp-route-id="@contact.Id">delete</button>
            </tbody>
        </table>
        <a asp-page="./Create">Create</a>
    </form>
    

    Index.cshtml.cs 隐藏文件:

    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using RazorPagesContacts.Data;
    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore;
    namespace RazorPagesContacts.Pages
        public class IndexModel : PageModel
            private readonly AppDbContext _db;
            public IndexModel(AppDbContext db)
                _db = db;
            public IList<Customer> Customers { get; private set; }
            public async Task OnGetAsync()
                Customers = await _db.Customers.AsNoTracking().ToListAsync();
            public async Task<IActionResult> OnPostDeleteAsync(int id)
                var contact = await _db.Customers.FindAsync(id);
                if (contact != null)
                    _db.Customers.Remove(contact);
                    await _db.SaveChangesAsync();
                return RedirectToPage();
    

    Index.cshtml 文件包含以下标记来创建每个联系人项的编辑链接:

    <a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
    

    定位点标记帮助程序 使用 asp-route-{value} 属性生成“编辑”页面的链接。 此链接包含路由数据及联系人 ID 。 例如 http://localhost:5000/Edit/1

    Pages/Edit.cshtml 文件:

    @page "{id:int}"
    @model RazorPagesContacts.Pages.EditModel
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
        ViewData["Title"] = "Edit Customer";
    <h1>Edit Customer - @Model.Customer.Id</h1>
    <form method="post">
        <div asp-validation-summary="All"></div>
        <input asp-for="Customer.Id" type="hidden" />
            <label asp-for="Customer.Name"></label>
                <input asp-for="Customer.Name" />
                <span asp-validation-for="Customer.Name" ></span>
            <button type="submit">Save</button>
    </form>
    

    第一行包含 @page "{id:int}" 指令。 路由约束 "{id:int}" 告诉页面接受包含 int 路由数据的页面请求。 如果页面请求未包含可转换为 int 的路由数据,则运行时返回 HTTP 404(未找到)错误。 若要使 ID 可选,请将 ? 追加到路由约束:

    @page "{id:int?}"
    

    Pages/Edit.cshtml.cs 文件:

    using System;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.EntityFrameworkCore;
    using RazorPagesContacts.Data;
    namespace RazorPagesContacts.Pages
        public class EditModel : PageModel
            private readonly AppDbContext _db;
            public EditModel(AppDbContext db)
                _db = db;
            [BindProperty]
            public Customer Customer { get; set; }
            public async Task<IActionResult> OnGetAsync(int id)
                Customer = await _db.Customers.FindAsync(id);
                if (Customer == null)
                    return RedirectToPage("/Index");
                return Page();
            public async Task<IActionResult> OnPostAsync()
                if (!ModelState.IsValid)
                    return Page();
                _db.Attach(Customer).State = EntityState.Modified;
                    await _db.SaveChangesAsync();
                catch (DbUpdateConcurrencyException)
                    throw new Exception($"Customer {Customer.Id} not found!");
                return RedirectToPage("/Index");
    

    Index.cshtml 文件还包含用于为每个客户联系人创建删除按钮的标记:

    <button type="submit" asp-page-handler="delete" 
            asp-route-id="@contact.Id">delete</button>
    

    删除按钮采用 HTML 呈现,其 formaction 包括参数:
    asp-route-id 属性指定的客户联系人 ID。
    asp-page-handler 属性指定的 handler

    下面是呈现的删除按钮的示例,其中客户联系人 ID 为 1

    <button type="submit" formaction="/?id=1&amp;handler=delete">delete</button>
    

    选中按钮时,向服务器发送窗体 POST 请求。 按照惯例,根据方案 OnPost[handler]Async 基于 handler 参数的值来选择处理程序方法的名称。

    因为本示例中 handlerdelete ,因此 OnPostDeleteAsync 处理程序方法用于处理 POST 请求。 如果 asp-page-handler 设置为不同值(如 remove ),则选择名称为 OnPostRemoveAsync 的页面处理程序方法。

    public async Task<IActionResult> OnPostDeleteAsync(int id)
        var contact = await _db.Customers.FindAsync(id);
        if (contact != null)
            _db.Customers.Remove(contact);
            await _db.SaveChangesAsync();
        return RedirectToPage();
    

    OnPostDeleteAsync 方法:
    接受来自查询字符串的 id
    使用 FindAsync 查询客户联系人的数据库。
    如果找到客户联系人,则从客户联系人列表将其删除。 数据库将更新。
    调用 RedirectToPage ,重定向到根索引页 (/Index) 。

    XSRF/CSRF 和 Razor 页面

    无需为防伪验证编写任何代码。Razor 页面自动将防伪标记生成过程和验证过程包含在内。

    将布局、分区、模板和标记帮助程序用于 Razor 页面

    页面可使用 Razor 视图引擎的所有功能。 布局、分区、模板、标记帮助程序、 _ViewStart.cshtml 和 _ViewImports.cshtml 的工作方式与它们在传统的 Razor 视图中的工作方式相同。

    我们来使用其中的一些功能来整理此页面。

    向 Pages/_Layout.cshtml 添加布局页面

    <!DOCTYPE html>
        <title>Razor Pages Sample</title>      
    </head>
       <a asp-page="/Index">Home</a>
        @RenderBody()  
        <a asp-page="/Customers/Create">Create</a> <br />
    </body>
    </html>
    
  • 控制每个页面的布局(页面选择退出布局时除外)。
  • 导入 HTML 结构,例如 JavaScript 和样式表。
  • 请参阅布局页面了解详细信息。

    在 Pages/_ViewStart.cshtml 中设置 Layout 属性:

    Layout = "_Layout";

    注意:布局位于“页面”文件夹中。 页面按层次结构从当前页面的文件夹开始查找其他视图(布局、模板、分区)。 可以从“页面”文件夹下的任意 Razor 页面使用“页面”文件夹中的布局。

    建议不要将布局文件放在“视图/共享”文件夹中。 视图/共享 是一种 MVC 视图模式。Razor 页面旨在依赖文件夹层次结构,而非路径约定。

    Razor 页面中的视图搜索包含“页面”文件夹。 用于 MVC 控制器和传统 Razor 视图的布局、模板和分区可直接工作。

    添加 Pages/_ViewImports.cshtml 文件:

    @namespace RazorPagesContacts.Pages
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    

    本教程的后续部分中将介绍 @namespace@addTagHelper 指令将内置标记帮助程序引入“页面”文件夹中的所有页面。

    页面上显式使用 @namespace 指令后:

    @page
    @namespace RazorPagesIntro.Pages.Customers
    @model NameSpaceModel
    <h2>Name space</h2>
        @Model.Message
    

    此指令将为页面设置命名空间。 @model 指令无需包含命名空间。
    _ViewImports.cshtml 中包含 @namespace 指令后,指定的命名空间将为在导入 @namespace 指令的页面中生成的命名空间提供前缀。 生成的命名空间的剩余部分(后缀部分)是包含 _ViewImports.cshtml 的文件夹与包含页面的文件夹之间以点分隔的相对路径。

    例如,代码隐藏文件 Pages/Customers/Edit.cshtml.cs 显式设置命名空间:

    namespace RazorPagesContacts.Pages
        public class EditModel : PageModel
            private readonly AppDbContext _db;
            public EditModel(AppDbContext db)
                _db = db;
            // Code removed for brevity.
    

    Pages/_ViewImports.cshtml 文件设置以下命名空间:

    @namespace RazorPagesContacts.Pages
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    

    为 Pages/Customers/Edit.cshtml Razor 页面生成的命名空间与代码隐藏文件相同. 已对 @namespace 指令进行设计,因此添加到项目的 C# 类和页面生成的代码可直接工作,而无需添加代码隐藏文件的 @using 指令。

    注意: @namespace 也可用于传统的 Razor 视图。

    原始的 Pages/Create.cshtml 视图文件:

    @page
    @model RazorPagesContacts.Pages.CreateModel
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
            Enter your name.
        <div asp-validation-summary="All"></div>
        <form method="POST">
            <div>Name: <input asp-for="Customer.Name" /></div>
            <input type="submit" />
        </form>
    </body>
    </html>
    

    更新后的 Pages/Create.cshtml 视图文件:

    @page
    @model CreateModel
            Enter your name.
        <div asp-validation-summary="All"></div>
        <form method="POST">
            <div>Name: <input asp-for="Customer.Name" /></div>
            <input type="submit" />
        </form>
    </body>
    </html>
    

    页面的 URL 生成

    之前显示的 Create 页面使用 RedirectToPage

    public async Task<IActionResult> OnPostAsync()
        if (!ModelState.IsValid)
            return Page();
        _db.Customers.Add(Customer);
        await _db.SaveChangesAsync();
        return RedirectToPage("/Index");
    

    应用具有以下文件/文件夹结构:

  • /Pages
  • Index.cshtml
  • /Customer
  • Create.cshtml
  • Edit.cshtml
  • Index.cshtml
  • 成功后, Pages/Customers/Create.cshtml 和 Pages/Customers/Edit.cshtml 页面将重定向到 Pages/Index.cshtml 。字符串 /Index 是用于访问上一页的 URI 的组成部分。可以使用字符串 /Index 生成 Pages/Index.cshtml 页面的 URI 。例如:

  • Url.Page("/Index", ...)
  • <a asp-page="/Index">My Index Page</a>
  • RedirectToPage("/Index")
  • 页面名称是从根“/Pages”文件夹到页面的路径(包含前导 / ,例如 /Index )。相较于仅对 URL 硬编码,前面的 URL 生成示例的功能更加强大。URL 生成使用路由,并且可以根据目标路径定义路由的方式生成参数并对参数编码。

    页面的URL生成支持相对名称。 下表显示了 Pages/Customers/Create.cshtml 中不同的 RedirectToPage 参数选择的索引页:

    RedirectToPage(x)

    RedirectToPage("Index")RedirectToPage("./Index")RedirectToPage("../Index") 是相对名称。 结合 RedirectToPage 参数与当前页的路径来计算目标页面的名称。

    构建结构复杂的站点时,相对名称链接很有用。 如果使用相对名称链接文件夹中的页面,则可以重命名该文件夹。 所有链接仍然有效(因为这些链接未包含此文件夹名称)。

    TempData

    ASP.NET在控制器上公开了 TempData 属性。 此属性存储未读取的数据。 KeepPeek 方法可用于检查数据,而不执行删除。 多个请求需要数据时, TempData 有助于进行重定向。

    [TempData] 是 ASP.NET Core 2.0 中的新属性,在控制器和页面上受支持。

    下面的代码使用 TempData 设置 Message 的值:

    public class CreateDotModel : PageModel
        private readonly AppDbContext _db;
        public CreateDotModel(AppDbContext db)
            _db = db;
        [TempData]
        public string Message { get; set; }
        [BindProperty]
        public Customer Customer { get; set; }
        public async Task<IActionResult> OnPostAsync()
            if (!ModelState.IsValid)
                return Page();
            _db.Customers.Add(Customer);
            await _db.SaveChangesAsync();
            Message = $"Customer {Customer.Name} added";
            return RedirectToPage("./Index");
    

    Pages/Customers/Index.cshtml 文件中的以下标记使用 TempData 显示 Message 的值。

    <h3>Msg: @Model.Message</h3>
    

    Pages/Customers/Index.cshtml.cs页面模型将[TempData]属性应用到Message属性。

    [TempData]
    public string Message { get; set; }
    

    请参阅 TempData 了解详细信息。

    针对一个页面的多个处理程序

    以下页面使用 asp-page-handler 标记帮助程序为两个页面处理程序生成标记:

    @page
    @model CreateFATHModel
            Enter your name.
        <div asp-validation-summary="All"></div>
        <form method="POST">
            <div>Name: <input asp-for="Customer.Name" /></div>
            <input type="submit" asp-page-handler="JoinList" value="Join" />
            <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
        </form>
    </body>
    </html>
    

    前面示例中的窗体包含两个提交按钮,每个提交按钮均使用 FormActionTagHelper 提交到不同的 URL 。 asp-page-handlerasp-page 的配套属性。 asp-page-handler 生成提交到页面定义的各个处理程序方法的 URL 。未指定 asp-page ,因为示例已链接到当前页面。

    页面模型:

    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using RazorPagesContacts.Data;
    namespace RazorPagesContacts.Pages.Customers
        public class CreateFATHModel : PageModel
            private readonly AppDbContext _db;
            public CreateFATHModel(AppDbContext db)
                _db = db;
            [BindProperty]
            public Customer Customer { get; set; }
            public async Task<IActionResult> OnPostJoinListAsync()
                if (!ModelState.IsValid)
                    return Page();
                _db.Customers.Add(Customer);
                await _db.SaveChangesAsync();
                return RedirectToPage("/Index");
            public async Task<IActionResult> OnPostJoinListUCAsync()
                if (!ModelState.IsValid)
                    return Page();
                Customer.Name = Customer.Name?.ToUpper();
                return await OnPostJoinListAsync();
    

    前面的代码使用已命名处理程序方法。已命名处理程序方法通过采用名称中 On<HTTP Verb> 之后及 Async 之前的文本(如果有)创建。 在前面的示例中,页面方法是 OnPostJoinListAsync 和 OnPostJoinListUCAsync 。删除 OnPost 和 Async 后,处理程序名称为 JoinListJoinListUC

    <input type="submit" asp-page-handler="JoinList" value="Join" />
    <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
    

    使用前面的代码时,提交到 OnPostJoinListAsync 的 URL 路径为 http://localhost:5000/Customers/CreateFATH?handler=JoinList 。提交到 OnPostJoinListUCAsync 的 URL 路径为 http://localhost:5000/Customers/CreateFATH?handler=JoinListUC

    自定义路由

    如果你不喜欢 URL 中的查询字符串 ?handler=JoinList,可以更改路由,将处理程序名称放在 URL 的路径部分。可以通过在 @page 指令后面添加使用双引号括起来的路由模板来自定义路由。

    @page "{handler?}"
    @model CreateRouteModel
            Enter your name.
        <div asp-validation-summary="All"></div>
        <form method="POST">
            <div>Name: <input asp-for="Customer.Name" /></div>
            <input type="submit" asp-page-handler="JoinList" value="Join" />
            <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
        </form>
    </body>
    </html>
    

    前面的路由将处理程序放在了 URL 路径中,而不是查询字符串中。handler 前面的 ? 表示路由参数为可选。

    可以使用 @page 将其他段和参数添加到页面的路由中。 其中的任何内容均会被追加到页面的默认路由中。 不支持使用绝对路径或虚拟路径更改页面的路由(如 "~/Some/Other/Path" )。

    配置和设置

    若要配置高级选项,请在 MVC 生成器上使用 AddRazorPagesOptions 扩展方法:

    public void ConfigureServices(IServiceCollection services)
        services.AddMvc()
            .AddRazorPagesOptions(options =>
                options.RootDirectory = "/MyPages";
                options.Conventions.AuthorizeFolder("/MyPages/Admin");
    

    目前,可以使用 RazorPagesOptions 设置页面的根目录,或者为页面添加应用程序模型约定。 通过这种方式,我们在将来会实现更多扩展功能。

    若要预编译视图,请参阅 Razor 视图编译

    下载或查看示例代码.

    请参阅 Razor 页面入门,这篇文章以本文为基础编写。

    指定 Razor 页面位于内容根目录中

    默认情况下,Razor 页面位于 /Pages 目录的根位置。向 AddMvc 添加 WithRazorPagesAtContentRoot,以指定 Razor 页面位于应用的内容根目录 (ContentRootPath) 中:

    services.AddMvc()
        .AddRazorPagesOptions(options =>
        .WithRazorPagesAtContentRoot();
    

    指定 Razor 页面位于自定义根目录中

    AddMvc 添加 WithRazorPagesRoot,以指定 Razor 页面位于应用中自定义根目录位置(提供相对路径):

    services.AddMvc()
        .AddRazorPagesOptions(options =>
        .WithRazorPagesRoot("/path/to/razor/pages");
    
  • ASP.NET Core 简介