ASP.NET Core Razor Pages 中处理多个Form表单提交请求
admin
2022-03-04ASP.NET Core 中使用托管启动程序集
导航:
•Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
•
•IHostingStartup(托管启动)实现在从外部程序集启动时向应用程序添加增强功能。
•
•https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation/6.0.0-preview.2.21154.6
•
•
•"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
ASP.NET Core Razor Pages 中处理多个Form表单提交请求
在本视频中,我们将讨论如何在ASP.NET Core Razor Pages中handler方法的使用,它主要服务于多个表单提交请求的时候使用。
Razor Pages中的handler处理程序方法
ASP.NET Core Razor Pages框架使用命名约定来选择处理程序方法。考虑以下编辑学生
Razor Pages。
要加载此编辑学生 Razor
页面,浏览器会发出GET请求。为了处理此GET请求,ASP.NET Core Razor Pages框架在对应的PageModel类中查找一个名为OnGet()的方法。
单击更新
按钮时,浏览器会发出POST请求。为了处理此POST请求,ASP.NET Core Razor Pages框架在对应的PageModel类中寻找一种名为OnPost()的方法。
因此,以下是razor pages框架用于查找处理程序方法的命名约定。单词On
是请求动词的前缀。因此,对于GET请求,它将查找OnGet,而对于POST请求,它将查找OnPost。
Razor Pages上有多个Form表单
如果给定的 Razor Pages上有2个或更多表单,该怎么办呢。在以下 Razor Pages上,我们有2种需求业务,如下:。
- Form表单1-用于更新通知首选项
- Form表单2-用于更新学生数据
在Form表单1上-我们具有更新消息通知
按钮
在Form表单2-我们有更新
按钮
在EditModel类中,我们有以下2个处理程序方法
public void OnPostUpdateNotificationPreferences()
{
// 处理更新消息通知内容
}
public IActionResult OnPost(Student student)
{
// 处理更新学生信息的功能
}
在表单1上,单击 更新通知首选项
按钮时,我们希望OnPostUpdateNotificationPreferences()方法处理该请求。我们使用<form>
元素上的asp-page-handler
标记助手来指定它,如下所示。
OnPost前缀不是必需的,但是您可以根据需要指定它。
<form method="post" asp-page-handler="UpdateNotificationPreferences">
@*Form 1 - 消息通知配置开关*@
</form>
在Form 2上,当单击更新
按钮时,我们希望OnPost()方法处理该请求。我们使用<form>
元素上的asp-page-handler标记助手 来指定它,如下所示。
<form method="post" asp-page-handler="OnPost">
@*Form 2 - 处理学生数据*@
</form>
当更新通知首选项按钮被点击,处理程序名称在URL作为查询字符串参数传递。
http://localhost:2221/students/edit/2/?handler=updatenotificationpreferences
修改处理程序名称路由参数
如果您希望将处理程序名称updatenotificationpreferences
作为路由参数而不是查询字符串参数传递,请在视图文件中包含路由参数,如下。
@page "{id:min(1)}/{handler?}"
进行此更改后,现在将处理程序名称作为路由参数传递到URL中,生成的url如下。
http://localhost:2221/students/edit/1/updatenotificationpreferences/
Edit.cshtml视图
@page "{id:min(1)}/{handler?}"
@model StudentManagement.RazorPage.Pages.Students.EditModel
@{
ViewData["Title"] = "编辑";
// 如果学生没有照片信息,就默认给他一张空照片
var photoPath = "~/images/" + (Model.Student.PhotoPath ?? "noimage.png");
}
<div class="row">
<div class="col-md-12">
<h1>消息通知配置开关</h1>
<form method="post" asp-page-handler="UpdateNotificationPreferences">
<div class="form-check">
<input asp-for="Notify" class="form-check-input" />
<label asp-for="Notify" class="form-check-label">
允许接收消息通知信息
</label>
</div>
<button type="submit" class="btn btn-primary">
更新消息通知
</button>
@if (!string.IsNullOrEmpty(Model.Message))
{
<div class="alert alert-primary">
@Model.Message
</div>
}
</form>
<hr />
</div>
<div class="col-md-12">
<h1>编辑学生</h1>
<form method="post" class="mt-3">
@*使用隐藏的input标签来存储提交表单时需要的学生id*@
<input hidden asp-for="Student.Id" />
@*asp-for TagHelper 负责在处理在不同的标签中显示现有的数据*@
<div class="form-group row">
<label asp-for="Student.Name" class="col-sm-2 col-form-label">
</label>
<div class="col-sm-10">
<input asp-for="Student.Name" class="form-control" placeholder="Name">
</div>
</div>
<div class="form-group row">
<label asp-for="Student.Email" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Student.Email" class="form-control" placeholder="Email">
</div>
</div>
<div class="form-group row">
<label asp-for="Student.Major" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<select asp-for="Student.Major" class="custom-select mr-sm-2"
asp-items="Html.GetEnumSelectList<MajorEnum>()">
<option value="">请选择</option>
</select>
</div>
</div>
<div class="form-group row">
<label asp-for="Photo" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<div class="custom-file">
@*Photo属性类型是IFormFile,ASP. NET Core会根据这个属性自动创建一个FileUpload控件 *@
@* 有关更具体的信息在《深入浅出ASP.NET Core》那本书有介绍 *@
<input asp-for="Photo" class="custom-file-input form-control">
<label class="custom-file-label">更换图片</label>
</div>
</div>
</div>
@*显示有照片的学生信息*@
<div class="form-group row col-sm-4 offset-4">
<img class="imageThumbnail" src="@photoPath" asp-append-version="true" />
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">更新</button>
<a asp-page="/Students/Index" class="btn btn-primary">取消</a>
</div>
</div>
@section Scripts {
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(fileName);
});
});
</script>
}
</form>
</div>
</div>
Edit.cshtml.cs
public class EditModel : PageModel
{
private readonly IStudentRepository studentRepository;
private readonly IWebHostEnvironment webHostEnvironment;
public EditModel(IStudentRepository studentRepository,
IWebHostEnvironment webHostEnvironment)
{
this.studentRepository = studentRepository;
//使用 IWebHostEnvironment 服务,我们可以获取wwwroot文件夹下的路径地址信息
this.webHostEnvironment = webHostEnvironment;
}
//这是显示模板将用于的属性,显示现有的学生数据
public Student Student { get; set; }
// 我们使用这个属性来存储和处理新上传的照片
[BindProperty]
public IFormFile Photo { get; set; }
[BindProperty]
public bool Notify { get; set; }
public string Message { get; set; }
public IActionResult OnGet(int id)
{
Student = studentRepository.GetStudent(id);
if (Student == null)
{
return RedirectToPage("/NotFound");
}
return Page();
}
public IActionResult OnPost(Student student)
{
if (Photo != null)
{
//上传新照片的时候,需要检查当前学生是否有已经存在的照片,如果有的话,就需要删除它,再上传新照片。
if (student.PhotoPath != null)
{
string filePath = Path.Combine(webHostEnvironment.WebRootPath,
"images", student.PhotoPath);
System.IO.File.Delete(filePath);
}
// 将新照片保存到wwwroot/images文件夹中,并更新student 的PhotoPath属性
student.PhotoPath = ProcessUploadedFile();
}
Student = studentRepository.Update(student);
return RedirectToPage("Index");
}
public void OnPostUpdateNotificationPreferences(int id)
{
if (Notify)
{
Message = "您已经打开了消息通知功能";
}
else
{
Message = "你已经关闭了消息通知功能";
}
Student = _studentRepository.GetStudent(id);
}
private string ProcessUploadedFile()
{
string uniqueFileName = null;
if (Photo != null)
{
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "images");
uniqueFileName = Guid.NewGuid().ToString() + "_" + Photo.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
Photo.CopyTo(fileStream);
}
}
return uniqueFileName;
}
}
以上便是在一个 Razor Pages中处理多个表单的比较合理的实践,他可以帮助我们处理多个表单提交。