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>
示例代码中分别定义了OnGet
和OnPost
两个处理程序方法,它们分别处理Single.cshtml
的GET
请求和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()
方法将不会处理任何请求,即使表单的处理程序方法名称与之匹配。
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册