首页 / ASP.NET Core / 正文

[ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的处理程序方法(Handler Methods)(10)

5764 发布于: 2018-11-30 读完约需22分钟

ASP.NET Core Razor Pages中的处理程序方法(Handler Methods)

什么是处理程序方法(Hanlder Methods)?

上一节中,我们了解了Razor Pages中的PageModel类文件,这个类文件中包含了类似OnGet,OnPost等这样的方法,涉及到的业务逻辑在这些方法中处理。在Razor Pages中,类似OnGet,OnPost的方法叫做Handler Methods(处理程序方法),这些处理处理方法对应页面的请求方式和名称。

处理程序方法遵循特定的命名约定,命名方式在上一节中也已阐述过:

当请求到达页面模型类时,处理程序会按照约定的规则匹配模型中的方法,这个规则是On<verb>(即On+HTTP的请求方式)。比如要处理GET方式的HTTP请求,那么在页面模型类中创建一个OnGet()处理方法。页面模型类同时支持异步处理,只需要在方法后面添加Async的后缀。比如GET方法的异步方法为:OnGetAsync()。其它HTTP请求方式类似的道理,页面模型支持所有的HTTP请求方式,如:GET,POST,PUT,DELETE,HEAD,PATCH,OPTIONS等等。
其中,处理程序方法的访问修饰符必须是public,可以返回任何结果类型(返回类型可以是void,也可以是ActionResult,甚至Task)。

为了演示Razor Pages中的处理程序方法(Handler Methods),以下定义了一个单页面的Razor Pages视图页面,如:

/Pages/HandlerMethods/Single.cshtml*:

@page
@{
    Layout = null;
}
@functions{
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public void OnGet()
    {
        Name = "Rector";
    }

    public IActionResult OnPost()
    {
        if (Name == "Rector")
        {
            DisplayName = "超级管理员";
        }
        else
        {
            DisplayName = "管理员";
        }
        return Page();
    }
}
<p>Name:@Model.Name</p>
<p>Display name:@Model.DisplayName</p>
<form method="post">
    <input asp-for="Name" />
    <button type="submit">提交</button>
</form>

示例代码中分别定义了OnGetOnPost两个处理程序方法,它们分别处理Single.cshtmlGET请求和POST请求。

当我们在浏览器中打开页面http://localhost:57973/handlermethods/single 后,即发送了一个GET请求,Razor Pages应用程序捕获到这个请求后,再由请求处理管道处理,并根据路由规则定位到[/Pages/HanlderMethods/Single.cshtml]视图文件,最终,OnGet处理程序方法与这个GET请求匹配而被执行。

所以,初次在浏览器中被渲染的只有Name这个值,输出的HTML如下:

<p>Name:Rector</p>
<p>Display name:</p>
...

当我们点击表单中的[提交]按钮后,由于表单的method="post",所以会匹配处理程序方法的OnPost,浏览器输出的HTML如下:

<p>Name:</p>
<p>Display name:管理员</p>
...

使用自定义处理程序方法处理单页面提交多表单的请求

看到这里,上面的页面只包含了一个表单提交,这时可能你会有些疑惑了:“如果需要在一个页面提交多个表单,并且这些表单的处理程序方法都不相同,应该怎么办呢?”

我们能想到的,微软自然也是考虑到的,所以在Razor Pages中,专门提供了页面提交多个表单的方法,叫做:自定义处理程序方法,如下的示例代码:

[/Pages/HandlerMethods/Custom.cshtml]:

@page
@model RazorPagesDemoApplication.Pages.HandlerMethods.CustomModel
@{
    Layout = null;
}
<p>Handler name: @Model.HandlerName</p>
<form method="post">
    <button type="submit" asp-page-handler="create">Create</button>
</form>
<hr />
<form method="post">
    <button type="submit" asp-page-handler="edit">Edit</button>
</form>
<hr />
<form method="post">
    <button type="submit" asp-page-handler="delete">Delete</button>
</form>

[/Pages/HandlerMethods/Custom.cshtml.cs]:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesDemoApplication.Pages.HandlerMethods
{
    public class CustomModel : PageModel
    {
        /// <summary>
        /// 当前匹配的处理程序方法名称
        /// </summary>
        public string HandlerName { get; set; }
        public void OnGet()
        {

        }

        /// <summary>
        /// 处理程序方法:Create
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPostCreate()
        {
            HandlerName = "create hanlder";
            return Page();
        }

        /// <summary>
        /// 处理程序方法:Edit
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPostEdit()
        {
            HandlerName = "edit hanlder";
            return Page();
        }

        /// <summary>
        /// 处理程序方法:Delete
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPostDelete()
        {
            HandlerName = $"delete hanlder" ;
            return Page();
        }
    }
}

[Custom.cshtml]文件中的三个表单包含了三个不同的请求按钮并分别设置了不同的asp-page-handler属性:asp-page-handler="create",asp-page-handler="edit",asp-page-handler="delete",它们分别对应[Custom.cshtml.cs]服务端代码中的:OnPostCreate,OnPostEdit,OnPostDelete处理程序方法。

当分别点击页面中的不同按钮时,PageModel中的HandlerName属性值会不同,如下图所示:

自定义处理程序方法表单提交演示

生成的HTML表单源码如下:

<p>Handler name: create hanlder</p>
<form method="post">
    <button type="submit" formaction="/handlermethods/custom?handler=create">Create</button>
</form>
<hr />
<form method="post">
    <button type="submit" formaction="/handlermethods/custom?handler=edit">Edit</button>
</form>
<hr />
<form method="post">
    <button type="submit" formaction="/handlermethods/custom?handler=delete">Delete</button>
</form>

其中的formaction将被作为表单的提交地址发送到后端处理程序方法,Razor引擎根据asp-page-handler属性为我们自动生成了handler的参数。

处理程序路由配置

在了解了自定义处理程序方法处理多表单之后,我们看到在URL参数中,Razor引擎自动添加了形如?handler=edit这样的参数,那么是否可以不以问号的形式来追加处理程序的参数呢?

答案是肯定的。

在Razor Pages中,我们可以借助Razor Pages的路由系统来配置,让自定义处理程序方法的参数不以问号的形式出现在URL地址中,如将:

http://localhost:57973/handlermethods/custom?handler=create

变成:

http://localhost:57973/handlermethods/custom/create

只需要Razor视图页面的@page指令之后配置{handler?}参数即可,路由系统将自动匹配相应的路由规则,比如在上面的页面[/Pages/HandlerMethods/Custom.cshtml]的@page指令后添加{handler?},则该页面渲染后的HTML为:

<p>Handler name: </p>
<form method="post">
    <button type="submit" formaction="/handlermethods/custom/create">Create</button>
</form>
<hr />
<form method="post">
    <button type="submit" formaction="/handlermethods/custom/edit">Edit</button>
</form>
<hr />
<form method="post">
    <button type="submit" formaction="/handlermethods/custom/delete">Delete</button>
</form>

三个表单的formaction地址均已没有了问号和动态参数了。

处理程序方法参数传递和配置

处理程度方法除了可以支持多个表单提交之外,还支持接受参数,比如我们新增表单:

<form method="post">
    <button type="submit" asp-page-handler="preview">Preview</button>
    <input type="hidden" name="id" value="5" />
</form>

以及对应的处理程序方法:

/// <summary>
/// 处理程序方法:Preview
/// </summary>
/// <returns></returns>
public IActionResult OnPostPreview(int id)
{
    HandlerName = $"preview hanlder id:{id}";
    return Page();
}

点击Preview按钮,页面将输出结果:

Handler name: preview hanlder id:5

注意:表单里的name(这里为name="id")属性必须与服务端的处理程序方法(这里为OnPostPreview(int id))相同,否则不能匹配参数。

同样的,我们也可以借助标签帮助类的asp-route属性来传递参数,还是以Preview这个表单为例,修改Preview表单:

<form method="post">
    <button type="submit" asp-page-handler="preview" asp-route-id="5">Preview</button>
</form>

再次点击Preview按钮,页面将输出与上面相同的结果:

Handler name: preview hanlder id:5

此时的URL为:http://localhost:57973/handlermethods/custom/preview?id=5 ,如果需要将id参数配置为非动态参数,则可配置@page指令的路由规则为:

@page "{handler?}/{id?}"

点击”Preview”按钮,此时的路径变为: http://localhost:57973/handlermethods/custom/preview/5

同一表单提交到不同的处理程序方法

Razor Pages视图页面同时还支持将同一表单提交到不同的处理程序方法,只需要指定提交按钮的asp-page-handler的方法名称,比如:

<form method="post">
    <button type="submit" asp-page-handler="view">View</button>
    <button type="submit" asp-page-handler="preview">Preview</button>
</form>

服务端的处理程序方法为:

/// <summary>
/// 处理程序方法:View
/// </summary>
/// <returns></returns>
public IActionResult OnPostView()
{
    HandlerName = $"view hanlder";
    return Page();
}

/// <summary>
/// 处理程序方法:Preview
/// </summary>
/// <returns></returns>
public IActionResult OnPostPreview()
{
    HandlerName = $"preview hanlder";
    return Page();
}

如果不希望服务端的方法匹配处理请求,则可以设置[NonHandler],如:

[NonHandler]
public void OnGetMethod()
{
    ...
}

OnGetMethod()方法将不会处理任何请求,即使表单的处理程序方法名称与之匹配。

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [.NET/C#].NET/C#应用程序开发中如何解码(decode)HTML字符串?

下一篇: [ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的视图数据(ViewData)(11)

本文永久链接码友网 » [ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的处理程序方法(Handler Methods)(10)

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册