【问题标题】:Why is my file download from MVC controller returning HTTP 404为什么我从 MVC 控制器下载的文件返回 HTTP 404
【发布时间】:2021-07-14 15:38:14
【问题描述】:

我整天都在查看有关 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(端点 => { 端点.MapRazorPages(); 端点.MapControllerRoute( 名称:“默认”, 模式:“{controller=Home}/{action=Index}/{id?}”);

endpoints.MapAreaControllerRoute(
    name: "areas",
    areaName: "areas",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
});

我在某个地方犯了错误吗?是路由吗? 提前致谢!

【问题讨论】:

  • 控制器上是否有包含ExportData 操作的[Route(...)] 属性?
  • 我愿意...目前用[Area("r")][Route("r/[controller]/[action]")]装饰
  • 控制器名称是什么?
  • r 中的Route 不是一个额外的吗?试试/r/r/OtpLock/export 看看是否有效
  • 根据您的描述,如果您将[HttpGet("export")] 换成[ActionName("export")],它可能会起作用。

标签: javascript c# asp.net-core asp.net-core-mvc


【解决方案1】:

控制器上指定[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% 确定这是否适用于您的设置。

【讨论】:

    猜你喜欢
    • 2015-07-29
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2015-10-12
    相关资源
    最近更新 更多