【问题标题】:Generate download link based on HTTP POST response根据 HTTP POST 响应生成下载链接
【发布时间】:2019-07-22 11:06:01
【问题描述】:

我在 C# 中有一个方法,它基本上以 CSV 文件的形式生成一个字符串,如下所示:

 [HttpPost]
        [ActionName("ExportFolder")]
        [ValidateAntiForgeryToken]
        public string ExportFolder(int? folderId)
        {
            if (folderId != null)
            {
                using (var ctx = new myContextEntities())
                {
                    var uid = Convert.ToInt32(User.Identity.Name);

                    var itemsToExport = ctx.Items.Where(y => y.MyListId == folderId && y.UserId == uid).ToList();
                    var sw = new StringWriter();
                    sw.WriteLine("\"Title1\",\"Title2 \",\"Title3\",\"Title4\",\"Title5\"");
                    foreach (var item in itemsToExport)
                    {
                        sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"",
                            item.Title1,
                            item.Title2,
                            item.Title3,
                            item.Title4,
                            item.Title5
                            ));
                    }
                    return sw.ToString();
                }
            }
            return "error";
        }

基本上,这现在应该是一个准备好的“CSV”文件,一旦 POST 完成就可以下载了。

jQuery 部分如下所示:

   $(document).on("click", ".exportFolder", function () {
        $.post("/ItemManagement/ExportFolder", { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]', '#__AjaxAntiForgeryForm').val(), folderId: $(this).attr("ID") }).done(function (data) {

        // Now I should here download the file... 

        });
    });

但我现在不确定如何触发下载部分?有人可以帮帮我吗?

【问题讨论】:

  • 有人吗? =)

标签: c# asp.net asp.net-mvc asp.net-mvc-4 c#-4.0


【解决方案1】:

假设您有一个占位符元素,其中包含锚链接以调用控制器操作以下载文件,如下所示:

<div id="dlink">
</div>

然后您可以将生成的字符串存储在 TempDataSession 变量中,并将 CSV 文件名作为 JSON 响应返回:

[HttpPost]
[ActionName("ExportFolder")]
[ValidateAntiForgeryToken]
public JsonResult ExportFolder(int? folderId)
{
    if (folderId != null)
    {
        using (var ctx = new myContextEntities())
        {
                var uid = Convert.ToInt32(User.Identity.Name);

                var itemsToExport = ctx.Items.Where(y => y.MyListId == folderId && y.UserId == uid).ToList();
                var sw = new StringWriter();
                sw.WriteLine("\"Title1\",\"Title2 \",\"Title3\",\"Title4\",\"Title5\"");
                foreach (var item in itemsToExport)
                {
                    sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"",
                        item.Title1,
                        item.Title2,
                        item.Title3,
                        item.Title4,
                        item.Title5
                        ));
                }
                TempData["Contents"] = sw.ToString();
                return Json("FileName");
        }
    }
    return Json("error");
}

然后,根据TempData/Session内容,使用GET方法创建一个控制器动作,返回FileResult,当点击锚链接时触发文件下载:

[HttpGet]
public ActionResult DownloadCsv(string fileName)
{
    string csv = TempData["Contents"] as string;

    string fileNameWithExt = fileName + ".csv";

    // check if the CSV content exists
    if (!string.IsNullOrEmpty(csv))
    {
        return File(new System.Text.UTF8Encoding.GetBytes(csv), "text/csv", fileNameWithExt);
    }
    else
    {
        return new EmptyResult();
    }
}

最后通过在jQuery.post()done()函数中添加锚标签来创建下载链接:

$(document).on("click", ".exportFolder", function () {
    $.post("/ItemManagement/ExportFolder", { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]', '#__AjaxAntiForgeryForm').val(), folderId: $(this).attr("ID") }).done(function (data) {
        if (data == "error") {
            alert(data); // show error message
        }
        else {
            var placeholder = $('#dlink');

            // remove existing anchor links inside placeholder
            placeholder.empty();

            // generate new anchor link                
            $('<a href="@Url.Action("DownloadCsv", "ControllerName")' + '&fileName=' + data + '">Click here to download CSV file</a>').appendTo(placeholder);
        }
    });
});

请注意,您不能直接从$.post() 响应下载 CSV 文件,因为 AJAX 响应旨在保留在同一页面上,因此需要使用 GET 方法的另一个控制器操作来提供从生成的锚链接触发的下载功能。

PS:这里的占位符元素只是一个例子,你可以根据自己的需要进行修改。

参考资料:

Download CSV file in ASP.NET MVC

Creating an anchor in a div

【讨论】:

    猜你喜欢
    • 2012-08-05
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2016-01-23
    相关资源
    最近更新 更多