为什么我从 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。

要使此行为符合您的预期,有几个选项。例如:

  1. 使用 [ActionName("export")] 而不是 [HttpGet("export")]。这具有提供 export 作为 [action] 的值的效果,而不是默认值,即方法的名称 ExportData。它也不会向在控制器级别定义的路由添加任何额外内容。
  2. 删除 [HttpGet("export")] 属性并在代码级别重命名 ExportData 操作,方法是将 方法 重命名为 Export 而不是 ExportData.
  3. 您可以从控制器中删除 [Route(...)] 属性,并从操作中删除 [HttpGet(...)] 属性。这将恢复为使用基于约定的路由,您已使用 MapAreaControllerRoute 设置了该路由。这也需要上面的 #1 或 #2,但我不能 100% 确定这是否适用于您的设置。