MVC通过AJAX POST下载文件

时间:2017-06-05 19:39:56

标签: javascript ajax model-view-controller download

我想允许用户从下拉列表中选择要下载的文件。一旦他们做出选择,他们就可以点击下载按钮。但是,该文件无法正确下载。

这是用于生成和返回文件的控制器:

[HttpPost]
    public ActionResult DownloadReport(int? id, string templateChoice)
    {
        if (id == null)
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        try
        {
            byte[] file = GetReport(id, templateChoice);
            return File(file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ResumeReport.docx");
        }
        catch (InvalidOperationException)
        {
            return View();
        }
    }

按下生成报告按钮时调用的JavaScript函数是:

function downloadReport(InputID) {
        $.ajax({
            type: 'POST',
            url: '@Url.Action("DownloadReport", "UserProfiles")',
            data: JSON.stringify({ "ID": InputID, "TemplateChoice": $("#resumeTemplates").val() }),
            contentType: 'application/json; charset=utf-8'
        });
    }

在chrome中打开检查窗口并转到网络选项卡显示已收到文档数据,但不会像常规文件一样下载。

1 个答案:

答案 0 :(得分:0)

我似乎找到了一个工作解决方案,它可以重新加载页面,不会重定向用户,并且在按下下载按钮时不会在URL中显示任何多余的文本。我用以下内容替换了我当前的JavaScript函数:

function downloadReport(inputID) {
        window.location.href = '/UserProfiles/DownloadReport/?id=' + inputID + '&template=' + $('#resumeTemplates').val();
    }

我的控制器现在看起来像:

public ActionResult DownloadReport(int? id, string template)
    {
        if (id == null || template == null)
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        try
        {
            byte[] file = GetReport(id, template);
            return File(file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ResumeReport.docx");
        }
        catch (InvalidOperationException)
        {
            return View();
        }
    }

我还将其添加到我的RouteConfig.cs文件中:

routes.MapRoute(
            "DownloadReport",
            "{controller}/{action}/{id}/{template}",
            new { controller = "UserProfiles", action = "DownloadReport", id = UrlParameter.Optional, template = UrlParameter.Optional }
        );