asp.net MVC中通过ajax请求下载文件

tt0*_*206 2 javascript asp.net-mvc

我正在尝试通过 asp.net 中的 ajax 调用下载文件

我的 JavaScript:

var allData = dataSource.data();
    var query = new kendo.data.Query(allData);
    var data = query.filter(filters).data;
    var strAccountCodes = '';
    for (var i = 0; i < data.length; i++) {
        strAccountCodes += data[i].AccountCode + ",";
    }
$.ajax({
        url: '@Url.Action("GetHistoricalUsageApplicationFile", "HUProducts")',
        type: 'GET',
        data: { "accountCodes": strAccountCodes }
    });
Run Code Online (Sandbox Code Playgroud)

我的行动方法:

public ActionResult GetHistoricalUsageApplicationFile([DataSourceRequest]DataSourceRequest request, [FromBody] string accountCodes)
    {
        var HistoricalUsagesData = _enrollmentManagementRepository.GetHistoricalUsageApplicationFile(accountCodes);
        List<HistoricalUsageApplicationFileModel> HUApplications = _mapper.MapToNew<List<HistoricalUsageApplicationFileModel>>(HistoricalUsagesData);
        //var HistoricalUsageApplication = HUReport.ToDataSourceResult(request).Data;

        var output = new MemoryStream();
        var writer = new StreamWriter(output, Encoding.UTF8);

        writer.Write("CommodityCode,");
        writer.Write("CustomerTypeCode,");
        writer.Write("EnrollmentRequestId");
        writer.WriteLine();

        var list = HUApplications.ConvertToString();
        var single = list.Aggregate((x, y) => { return string.Concat(x, y); });

        writer.WriteAsync(single);
        writer.Flush();
        output.Position = 0;

        return File(output, System.Net.Mime.MediaTypeNames.Application.Octet, "Products.csv");
    }
Run Code Online (Sandbox Code Playgroud)

代码正在执行,没有任何错误,但没有下载任何文件。

这是我所缺少的吗?

Tet*_*oto 8

您应该知道 AJAX 调用并不是直接下载 CSV 文件。因此,您可以从实例创建一个字节数组MemoryStream并将其存储在变量中SessionTempData然后返回“成功”状态以在 AJAX 成功响应上启用重定向:

public ActionResult GetHistoricalUsageApplicationFile([DataSourceRequest]DataSourceRequest request, [FromBody] string accountCodes)
{
    var HistoricalUsagesData = _enrollmentManagementRepository.GetHistoricalUsageApplicationFile(accountCodes);
    List<HistoricalUsageApplicationFileModel> HUApplications = _mapper.MapToNew<List<HistoricalUsageApplicationFileModel>>(HistoricalUsagesData);
    //var HistoricalUsageApplication = HUReport.ToDataSourceResult(request).Data;

    var output = new MemoryStream();
    var writer = new StreamWriter(output, Encoding.UTF8);

    writer.Write("CommodityCode,");
    writer.Write("CustomerTypeCode,");
    writer.Write("EnrollmentRequestId");
    writer.WriteLine();

    var list = HUApplications.ConvertToString();
    var single = list.Aggregate((x, y) => { return string.Concat(x, y); });

    writer.WriteAsync(single);
    writer.Flush();
    output.Position = 0;

    // creates byte array from stream
    TempData["Output"] = output.ToArray();

    // returns successful state
    return Json("Success", JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)

其次,使用 GET 方法创建一个控制器操作,并将存储的字节数组传入SessionTempData传出FileResult

public ActionResult DownloadCSV()
{
    // retrieve byte array here
    var array = TempData["Output"] as byte[];
    if (array != null)
    {
        return File(array, System.Net.Mime.MediaTypeNames.Application.Octet, "Products.csv");
    }
    else
    {
        return new EmptyResult();
    }
} 
Run Code Online (Sandbox Code Playgroud)

最后,处理success包含的响应,该响应将重定向到返回下载 CSV 文件的location.href控制器:FileResult

$.ajax({
    url: '@Url.Action("GetHistoricalUsageApplicationFile", "HUProducts")',
    type: 'GET',
    data: { "accountCodes": strAccountCodes },
    success: function (result) {
        if (result == "Success") {
            location.href = '@Url.Action("DownloadCSV", "ControllerName")';
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

作为一个选项,您可以使用查询字符串将 CSV 文件名作为来自 AJAX 响应的参数传递。

相关问题:

从流创建字节数组