为什么我从 MVC 控制器下载的文件返回 HTTP 404
Why is my file download from MVC controller returning HTTP 404
我一整天都在查看有关 SO 的问题,但我觉得我在这里一无所获,所以我求助于社区。希望各位高手帮帮我。
我的项目中有以下控制器操作:
[HttpGet("export")]
public IActionResult ExportData(string exportType, DateTime? fromDate, DateTime toDate, string search, bool? locked)
{
// Load the data from the db.
var data = LoadData(fromDate, toDate, locked, search);
bytes[] contentBytes = new byte[] { };
switch (exportType)
{
case "csv":
contentBytes = DataHelpers.ExportDataToCSV(data);
break;
// Other cases removed for brevity.
}
var content = new MemoryStream(contentBytes);
return File(content, MediaTypeNames.Application.Octet, "Report.csv");
}
老实说,我不确定导出是否有效,因为我的 ajax 查询中一直收到 HTTP 404:
function dataExport(type) {
const search = document.getElementById("GridSearch").value;
const fromDate = document.getElementById("startDate").value;
const toDate = document.getElementById("endDate").value;
const locked = document.getElementById("LockedStatus").checked;
let args = "?exportType=" + type + "&";
if (search !== null && search.length >= 1) {
args += "search=" + search + "&";
}
if (fromDate !== null && fromDate.length >= 1) {
args += "fromDate=" + fromDate + "&";
}
if (toDate !== null && toDate.length >= 1) {
args += "toDate=" + toDate + "&";
}
if (locked === true || locked === false) {
args += "locked=" + locked
}
if (args.endsWith("&")) {
args = args.substr(0, args.length - 1);
}
// Path is /[area]/[controller]/[action]
// Url output = /r/OtpLock/export?exportType=csv&search=foo
$.get("/r/OtpLock/export" + args, null, function (data) {
console.log(data);
});
}
我没想到这里会出现 404,因为它实际上只是在触发控制器操作,所以我想也许我的路由不起作用?
app.UseEndpoints(端点=>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
名称:“默认”,
模式:“{controller=Home}/{action=Index}/{id?}”);
endpoints.MapAreaControllerRoute(
name: "areas",
areaName: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
});
我是不是哪里弄错了?是路由吗?
提前致谢!
在 控制器 上指定了路由模板 [Route("r/[controller]/[action]")]
,ExportData
操作的路由变为:
r/OtpLock/ExportData
将 [HttpGet("export")]
添加到 ExportData
方法会附加一个现有段 export
,这会将其路由更改为:
r/OtpLock/ExportData/export
这不是您用于 AJAX 调用的 URL,因此服务器响应 404。
要使此行为符合您的预期,有几个选项。例如:
- 使用
[ActionName("export")]
而不是 [HttpGet("export")]
。这具有提供 export
作为 [action]
的值的效果,而不是默认值,即方法的名称 ExportData
。它也不会向在控制器级别定义的路由添加任何额外内容。
- 删除
[HttpGet("export")]
属性并在代码级别重命名 ExportData
操作,方法是将 方法 重命名为 Export
而不是 ExportData
.
- 您可以从控制器中删除
[Route(...)]
属性,并从操作中删除 [HttpGet(...)]
属性。这将恢复为使用基于约定的路由,您已使用 MapAreaControllerRoute
设置了该路由。这也需要上面的 #1 或 #2,但我不能 100% 确定这是否适用于您的设置。
我一整天都在查看有关 SO 的问题,但我觉得我在这里一无所获,所以我求助于社区。希望各位高手帮帮我。 我的项目中有以下控制器操作:
[HttpGet("export")]
public IActionResult ExportData(string exportType, DateTime? fromDate, DateTime toDate, string search, bool? locked)
{
// Load the data from the db.
var data = LoadData(fromDate, toDate, locked, search);
bytes[] contentBytes = new byte[] { };
switch (exportType)
{
case "csv":
contentBytes = DataHelpers.ExportDataToCSV(data);
break;
// Other cases removed for brevity.
}
var content = new MemoryStream(contentBytes);
return File(content, MediaTypeNames.Application.Octet, "Report.csv");
}
老实说,我不确定导出是否有效,因为我的 ajax 查询中一直收到 HTTP 404:
function dataExport(type) {
const search = document.getElementById("GridSearch").value;
const fromDate = document.getElementById("startDate").value;
const toDate = document.getElementById("endDate").value;
const locked = document.getElementById("LockedStatus").checked;
let args = "?exportType=" + type + "&";
if (search !== null && search.length >= 1) {
args += "search=" + search + "&";
}
if (fromDate !== null && fromDate.length >= 1) {
args += "fromDate=" + fromDate + "&";
}
if (toDate !== null && toDate.length >= 1) {
args += "toDate=" + toDate + "&";
}
if (locked === true || locked === false) {
args += "locked=" + locked
}
if (args.endsWith("&")) {
args = args.substr(0, args.length - 1);
}
// Path is /[area]/[controller]/[action]
// Url output = /r/OtpLock/export?exportType=csv&search=foo
$.get("/r/OtpLock/export" + args, null, function (data) {
console.log(data);
});
}
我没想到这里会出现 404,因为它实际上只是在触发控制器操作,所以我想也许我的路由不起作用? app.UseEndpoints(端点=> { endpoints.MapRazorPages(); endpoints.MapControllerRoute( 名称:“默认”, 模式:“{controller=Home}/{action=Index}/{id?}”);
endpoints.MapAreaControllerRoute(
name: "areas",
areaName: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
});
我是不是哪里弄错了?是路由吗? 提前致谢!
在 控制器 上指定了路由模板 [Route("r/[controller]/[action]")]
,ExportData
操作的路由变为:
r/OtpLock/ExportData
将 [HttpGet("export")]
添加到 ExportData
方法会附加一个现有段 export
,这会将其路由更改为:
r/OtpLock/ExportData/export
这不是您用于 AJAX 调用的 URL,因此服务器响应 404。
要使此行为符合您的预期,有几个选项。例如:
- 使用
[ActionName("export")]
而不是[HttpGet("export")]
。这具有提供export
作为[action]
的值的效果,而不是默认值,即方法的名称ExportData
。它也不会向在控制器级别定义的路由添加任何额外内容。 - 删除
[HttpGet("export")]
属性并在代码级别重命名ExportData
操作,方法是将 方法 重命名为Export
而不是ExportData
. - 您可以从控制器中删除
[Route(...)]
属性,并从操作中删除[HttpGet(...)]
属性。这将恢复为使用基于约定的路由,您已使用MapAreaControllerRoute
设置了该路由。这也需要上面的 #1 或 #2,但我不能 100% 确定这是否适用于您的设置。