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 属性

待更新

相关推荐
超爱吃士力架42 分钟前
邀请逻辑
java·linux·后端
AskHarries3 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion4 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp4 小时前
Spring-AOP
java·后端·spring·spring-aop
TodoCoder4 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
凌虚5 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
机器之心6 小时前
图学习新突破:一个统一框架连接空域和频域
人工智能·后端
.生产的驴7 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
顽疲7 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端
机器之心7 小时前
AAAI 2025|时间序列演进也是种扩散过程?基于移动自回归的时序扩散预测模型
人工智能·后端