Создать ссылку для скачивания на основе ответа HTTP POST - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть метод в 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... 

        });
    });

Но я сейчас не уверен, как вызвать часть загрузки?Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 01 марта 2019

Предположим, у вас есть элемент-заполнитель, который будет содержать якорную ссылку на действие контроллера вызова для загрузки файла, подобного этому:

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

Затем вы можете сохранить сгенерированную строку внутри TempData или Sessionпеременная и возвращает имя файла 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");
}

Затем создайте действие контроллера с методом GET, чтобы вернуть FileResult, который инициирует загрузку файла при нажатии на ссылку привязки, в соответствии с TempData / Session content:

[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();
    }
}

И, наконец, создайте ссылку для загрузки, добавив тег привязки в done() функцию jQuery.post():

$(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);
        }
    });
});

Обратите внимание, что вы не можете напрямую загрузить файл CSV из$.post() ответ, потому что ответ AJAX предназначен для того, чтобы остаться на той же странице, поэтому необходимо другое действие контроллера с методом GET, чтобы обеспечить функциональность загрузки, которая запускается из сгенерированной ссылки привязки.

PS: Элемент-заполнитель здесь является лишь примером, вы можете изменить его в зависимости от ваших потребностей.

Ссылки:

ЗагрузитьCSV-файл в ASP.NET MVC

Создание привязки в div

...