ASP.NET Razor Pages中如何用Fetch API调用命名处理方法?
问题描述
我正在使用内嵌Fetch API脚本将文件上传至存储服务器,现有HTML表单、Fetch请求脚本及后端处理代码如下:
HTML表单代码
<form method="post" class="col-sm-6"> <div class="form-group row"> <label asp-for="UploadedFile" class="col-sm-3 col-form-label"></label> <div class="col-sm-7"> <input asp-for="UploadedFile" class="form-control"> </div> </div> <div class="form-group row"> <div class="col-sm-7 offset-sm-3"> <button asp-page-handler="Upload" class="btn btn-primary" id="submit">Submit</button> </div> </div> </form>
Fetch请求脚本
document.getElementById('submit').addEventListener("click", (evt) => { evt.preventDefault(); let data = new FormData(document.forms[0]); fetch('', { method: 'post', body: data }) .then(() => { alert('File Uploaded'); }); });
后端处理代码(原可正常运行版本)
public async Task<IActionResult> OnPost(IFormFile uploadedFile) { IFormFile? uploadedFormFile = uploadedFile; if (uploadedFormFile.Length > 0) { string? filePath = Path.Combine(_databaseUploadPath, uploadedFormFile.FileName); using (FileStream? databaseStream = System.IO.File.Create(filePath)) { databaseStream.Position = 0; await uploadedFormFile.CopyToAsync(databaseStream); } } return new EmptyResult(); }
现在希望将后端处理方法重命名为OnPostUpload(命名处理方法),但静态页中常用的asp-page-handler标签在此Fetch请求场景下无效,请问如何在客户端的Fetch请求中指定特定的端点处理方法?
解决方案
在ASP.NET Razor Pages中,命名处理方法需要通过handler查询参数来指定,同时必须携带防伪造令牌(Razor Pages默认要求POST请求验证防伪造令牌,否则会返回400错误),具体有两种实现方式:
方式一:在Fetch请求URL中添加handler参数
- 先修改后端方法为命名处理方法:
public async Task<IActionResult> OnPostUpload(IFormFile uploadedFile) { IFormFile? uploadedFormFile = uploadedFile; if (uploadedFormFile.Length > 0) { string? filePath = Path.Combine(_databaseUploadPath, uploadedFormFile.FileName); using (FileStream? databaseStream = System.IO.File.Create(filePath)) { databaseStream.Position = 0; await uploadedFormFile.CopyToAsync(databaseStream); } } return new EmptyResult(); }
- 修改Fetch脚本,在URL中加入
?handler=Upload,并添加防伪造令牌到请求头:
document.getElementById('submit').addEventListener("click", (evt) => { evt.preventDefault(); let data = new FormData(document.forms[0]); // 获取页面自动生成的防伪造令牌 const token = document.querySelector('input[name="__RequestVerificationToken"]').value; fetch('?handler=Upload', { method: 'post', headers: { 'RequestVerificationToken': token }, body: data }) .then(response => { if (!response.ok) throw new Error('上传失败'); alert('File Uploaded'); }) .catch(err => alert(err.message)); });
方式二:将handler参数加入FormData中
这种方式无需修改URL,直接把handler参数加入FormData即可(防伪造令牌会被表单自动包含进FormData):
document.getElementById('submit').addEventListener("click", (evt) => { evt.preventDefault(); let data = new FormData(document.forms[0]); // 添加handler参数,对应后端OnPostUpload方法的后缀Upload data.append('handler', 'Upload'); fetch('', { method: 'post', body: data }) .then(response => { if (!response.ok) throw new Error('上传失败'); alert('File Uploaded'); }) .catch(err => alert(err.message)); });
内容的提问来源于stack exchange,提问作者Danny Hepple
相关产品推荐
相关产品推荐

