ASP.NET Core 中的 Razor Pages

Razor Pages

Razor Pages 是基于页面的 ASP.NET Core Web App 架构。

相比 MVC 模式,Razor Pages的生产效率更快。

Razer Pages 需要两个中间件:

  • builder...Services.AddRazorPages 添加 Razor Pages services
  • app.MapRazorPages 添加 Razor Pages endpoints

.cshtml 与 .cshtml.cs

在最简单的页面中:

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

看起来与 MVC 的页面差不多,但特别之处是有一个 @page 指令,@page 指令意味着这个页面可以直接接收 http request,而不需要通过 controller。

第2个页面Pages/Index2.cshtml 的代码是这样的:

html 复制代码
@page
@using RazorPagesIntro.Pages
@model Index2Model

<h2>Separate page model</h2>
<p>
    @Model.Message
</p>

使用了 @using RazorPagesIntro.Pages 指令,

而RazorPagesIntro.Pages的实现代码Pages/Index2.cshtml.cs是这样的:

csharp 复制代码
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;

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

一个Index2.cshtml 页面,搭配一个Index2.cshtml.cs,类似WPF 中的 xaml与 xaml.cs。

URL Path 路由

url 的 Path 与页面的 path 相匹配。比如:

  • / or /Index 匹配 /Pages/Index.cshtml
  • /Contact 匹配 /Pages/Contact.cshtml
  • /Store/Contact 匹配 /Pages/Store/Contact.cshtml

一个 Post 例子

有一个Pages/Customers/Create.cshtml 的 view 页面,代码如下:

@model 指令中的CreateModel 对应一个名为 Create 的 Model,

而 Form 的 submit 会发生 Http Post,

html 复制代码
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<p>Enter a customer name:</p>

<form method="post">
    Name:
    <input asp-for="Customer!.Name" />
    <input type="submit" />
</form>

相应的Pages/Customers/Create.cshtml.cs 的代码中的部分如下:

OnPostAsync 处理 cshtml 中的 form submit,

一般还会有一个OnGet方法处理Http Get 请求。

RedirectToPage 方法会重定向到 ./Index 路径。

BindProperty 注解属性是表示model binding。

Razor Pages 中的BindProperty 一般用于非 GET 的属性。

csharp 复制代码
[BindProperty]
public Customer? Customer { get; set; }

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }
    if (Customer != null) _context.Customer.Add(Customer);
    return RedirectToPage("./Index");
}

Home Page 的例子

Index.cshtml

html 复制代码
@page
@model RazorPagesContacts.Pages.Customers.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<h1>Contacts home page</h1>
<form method="post">
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        @if (Model.Customers != null)
        {
            foreach (var contact in Model.Customers)
            {
                <tr>
                    <td> @contact.Id </td>
                    <td>@contact.Name</td>
                    <td>
                        <!-- <snippet_Edit> -->
                        <a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
                        <!-- </snippet_Edit> -->
                        <!-- <snippet_Delete> -->
                        <button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
                        <!-- </snippet_Delete> -->
                    </td>
                </tr>
            }
        }
        </tbody>
    </table>
    <a asp-page="Create">Create New</a>
</form>

其中的

html 复制代码
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |

使用asp-route-id 生成指向Edit页面的URL,URL 中包含 Contact id,比如:

https://localhost:5001/Edit/1

而delete方法的html

html 复制代码
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>

由 server 生成后的html是:

html 复制代码
<button type="submit" formaction="/Customers?id=1&amp;handler=delete">delete</button>

对应的 Model 的代码Index.cshtml.cs:

csharp 复制代码
public class IndexModel : PageModel
{
    private readonly Data.CustomerDbContext _context;
    public IndexModel(Data.CustomerDbContext context)
    {
        _context = context;
    }

    public IList<Customer>? Customers { get; set; }

    public async Task OnGetAsync()
    {
        Customers = await _context.Customer.ToListAsync();
    }

    public async Task<IActionResult> OnPostDeleteAsync(int id)
    {
        var contact = await _context.Customer.FindAsync(id);

        if (contact != null)
        {
            _context.Customer.Remove(contact);
            await _context.SaveChangesAsync();
        }

        return RedirectToPage();
    }
}

使用Layouts,Partial,模板和Tag Helpers

待更新

URL Generation

待更新

ViewData 属性

待更新

TempData 属性

待更新

相关推荐
红尘散仙1 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记3 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
会编程的土豆3 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
喵个咪3 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
basketball6164 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
qq_2518364574 小时前
SpringBoot+Vue 共享电池柜管理系统 完整实现 前后端分离项目实战 完整代码
vue.js·spring boot·后端
zhangxingchao4 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
IT_陈寒5 小时前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端
ayqy贾杰6 小时前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理
Apifox6 小时前
Apifox 5 月更新|Postman 导入优化、Runner 支持非 root 运行、请求代码自动带鉴权
前端·后端·安全