【问题标题】:When downloading file in ASP.Net Core, my file is returned from server correctly, but does not save from UI [duplicate]在 ASP.Net Core 中下载文件时,我的文件从服务器正确返回,但没有从 UI [重复]
【发布时间】:2020-07-19 14:07:04
【问题描述】:

我的 UI 上有一个数据网格,它允许用户从文件列表中进行选择。选择后,会出现一个下载按钮,按下该按钮后,通过 Ajax 将文件 id 传递给我的控制器,然后获取文件并使用 File(fileStream, contentType, fileDownloadName) 将其返回到前端。

我唯一的问题是它没有保存在浏览器中。在浏览器中调试和检查后,服务器正在发送正确的响应,所以我被卡住了。非常感谢任何帮助。

另外,当我在浏览器中输入带有 ID 参数的整个 URL 时,它会成功下载,例如:https://localhost:44346/home/Download/?loadId=38

下面是相关代码:

// 带有数据网格和下载按钮的 HTML

        <div data-options="dxItem: { title: 'Load History', icon: 'find' } ">
            <div id="gridContainer2"></div>
            <div id="downloadButton"></div>
        </div>

// 具有通过 Id 获取文件并返回它的逻辑的控制器:

    [HttpGet]
    public async Task<IActionResult> Download(int loadId)
    {

        Console.WriteLine("Attempting to download Load ID: " + loadId + " from UI");

        var outputFolder = Directory.GetCurrentDirectory() + "\\wwwroot\\output\\";
        var name = GetFileName(loadId, outputFolder);
        var path = Path.Combine(outputFolder, name);

        var memory = new MemoryStream();

        if (loadId > 0)
        {
            try
            {
                using (var stream = new FileStream(path, FileMode.Open))
                {
                    await stream.CopyToAsync(memory);
                }

                memory.Position = 0;    
            }

            catch (Exception e)
            {
                Log.Error($"Unable to copy load {loadId} to memory for download: " + e);
            }

            Log.Info($"Results for file load: " + loadId + " download triggered successfully");

            return File(memory, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                "Downloaded.xlsx");
        }

        else
        {
            return new EmptyResult();
        }

    }


    public string GetFileName(int loadId, string outputFolder)
    {

        Log.Info($"Locating results for load {loadId} on web server");

        var resultsName = @"Results_Load_" + loadId + "_*";
        var results = "";
        var d = new DirectoryInfo(outputFolder);

        try
        {
            foreach (var file in d.GetFiles(resultsName))
            {
                Log.Info($"Results for load {loadId} located for download");
                results = file.Name;
            }
        }

        catch (Exception e)
        {
            Log.Error($"Results for load {loadId} not found on server: " + e);
            return null; 
        }

        return results; 

    }

//编辑:Jquery 添加:

//我的视图上的JQuery数据网格,当用户选择数据行时调用getLoadId方法:

    $("#gridContainer2").dxDataGrid({
        dataSource: DevExpress.data.AspNet.createStore({
            loadUrl: url + "/GetLoadHistory",
            key: "loadId"

        }),
        selection: {
            mode: "single"
        },
        hoverStateEnabled: true,
        paging: {
            pageSize: 10
        },

        editing: {
            mode: 'row',

        },
        onSelectionChanged: getLoadId
    });

//带有 Ajax 的 JQuery 函数将选定的 loadId 传递给控制器​​:

function getLoadId() {
    var dataGrid = $("#gridContainer2").dxDataGrid("instance");
    var loadIds = dataGrid.getSelectedRowKeys();
    var loadId = loadIds[0];

    if (loadId > 0)
    {
        console.log("Load ID: " + loadId);
        download(loadId);

    }
}

function download(loadId) {
    $("#downloadButton").dxButton({
        text: "Download Selected",
        type: "default",
        icon: "/favicon.ico",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        useSubmitBehavior: true,
        onClick: function(e) {
            $.ajax({
                url: 'https://localhost:44346/home/Download/',
                type: 'GET',
                data: {
                    loadId: loadId
                }
            }).done(function() {
                DevExpress.ui.notify("Downloading results for Load ID: " + loadId, "info", 1500);
            });
        }
    });

    console.log("Load ID: " + loadId + " download processed");

};

【问题讨论】:

  • 我们必须查看您的 javascript。如果您使用 ajax 从 javascript 调用控制器,则必须自己处理响应。
  • 干杯,现在添加

标签: c# html .net asp.net-core razor


【解决方案1】:

当使用 Ajax 时,浏览器不会自动对响应进行任何操作。它不会自动提供下载文件,就像它不会自动播放视频或显示图像一样。

您必须告诉浏览器该做什么。

你可以

  • 将用户重定向到下载 URL,而不是使用 Ajax。这是最简单的。试试看!
  • 收到响应后创建一个“url 对象”,并使用它在浏览器中启动“下载过程”。有关示例,请参阅 this answer

还有各种使用 iframe 之类的旧黑客,但这些天我会避免它们。

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 2013-08-30
    • 2016-10-22
    • 2021-08-22
    • 2015-06-14
    • 1970-01-01
    • 2019-08-03
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多