从视图中导出带有Ajax-Post的CSV-ASP.NET MVC5

时间:2019-01-31 08:49:41

标签: jquery ajax asp.net-mvc csv post

我正在尝试使用我的视图下载CSV文件。我调试了控制器方法,它起作用了,我可以看到结果,但是下载没有开始。 Network>Response

我的控制器:

[HttpPost]
    public FileContentResult ReportExecution(int reportId, string parameters)
    {
        var paramDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(parameters);

        var data = this._reportsRepository
            .ExecuteReport
            (
                reportId,
                paramDictionary
            );

        //Response.AddHeader("content-disposition", "attachment;filename=CsVExport.csv");

        return this.File(data, "text/csv", "CsVExport.csv");
    }

MyView:

...
</form>
<button onclick="submitForm()">Check Form</button>

<script>

    function submitForm() {
        var form = $('#form');

        var obj = {};
        var elements = $("input, select, textarea", form);

        for (var i = 0; i < elements.length; ++i) {
            var element = elements[i];
            var name = element.name;
            var value = element.value;

            if (name) {
                obj[name] = value;
            }
        }

        console.log(obj);
        $.post("ReportExecution", { reportId: @ViewBag.ReportId, parameters: JSON.stringify(obj) });

    }

</script>

不要问为什么要提交这个奇怪的程序。无法正常发送MVC5,因为我的表单非常动态,并且我无法将模型传递给控制器​​,因为它一直在变化。

1 个答案:

答案 0 :(得分:0)

您应该知道的第一件事是AJAX POST并非旨在执行文件下载操作。您可以使用GET方法创建一个控制器,以下载从ExecuteReport生成的文件:

[HttpGet]
public FileContentResult Download(string fileName)
{
    var data = TempData["CSVFile"] as ...; // specify the type returned by ExecuteReport here

    if (data != null && !string.IsNullOrEmpty(fileName))
    {
        fileName = fileName + ".csv";

        return File(data, "text/csv", fileName);
    }
    else
    {
        // something went wrong
        return new EmptyResult();
    }        
}

然后在AJAX调用中包含success函数,使用文件名作为参数重定向到上面提供的控制器,并使用TempData / Session变量传递文件内容:

AJAX POST

function submitForm() {
    var form = $('#form');

    var obj = {};

    // create object to pass into action parameter

    console.log(obj);
    $.post("ReportExecution", { reportId: @ViewBag.ReportId, parameters: JSON.stringify(obj) }, function (result) {
        location.href = '@Url.Action("Download", "ControllerName")' + '?fileName=' + result;
    });
}

POST操作

[HttpPost]
public ActionResult ReportExecution(int reportId, string parameters)
{
    var paramDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(parameters);

    var data = this._reportsRepository
        .ExecuteReport
        (
            reportId,
            paramDictionary
        );

    // pass file content to TempData or Session variable
    TempData["CSVFile"] = data;

    string fileName = "CsVExport";

    // pass file name to redirect into download action
    return Json(fileName);
}