admin管理员组

文章数量:1278853

I am trying to download file through ajax call in asp

my 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 }
    });

my action method:

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");
    }

code is executing without any errors but it's not downloading any file.

is that anything i am missing?

I am trying to download file through ajax call in asp

my 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 }
    });

my action method:

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");
    }

code is executing without any errors but it's not downloading any file.

is that anything i am missing?

Share Improve this question edited Feb 27, 2019 at 2:13 tt0206 asked Feb 27, 2019 at 2:06 tt0206tt0206 8473 gold badges11 silver badges30 bronze badges 4
  • What is strAccountCodes, is that server-side or client-side variable? Of course you cannot download file using AJAX, you need an ActionLink or normal redirect to GetHistoricalUsageApplicationFile action method. – Tetsuya Yamamoto Commented Feb 27, 2019 at 2:08
  • I have updated javascript code above. strAccountCodes is string which i am sending to GetHistoricalUsageApplicationFile action method. – tt0206 Commented Feb 27, 2019 at 2:14
  • @TetsuyaYamamoto can you explain how can i achieve this with ActionLink. – tt0206 Commented Feb 27, 2019 at 2:18
  • Based from your current code, I preferred using redirect rather than ActionLink - creating another controller which only serves file download is necessary. Then pass the stream result to Session or TempData. – Tetsuya Yamamoto Commented Feb 27, 2019 at 2:20
Add a ment  | 

1 Answer 1

Reset to default 9

You should know that AJAX call is not intended to download CSV file directly. Therefore, you can create a byte array from MemoryStream instance and store it inside Session or TempData variable, then return 'successful' state to enable redirect on AJAX success response:

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

Second, create a controller action with GET method and pass stored byte array from Session or TempData into 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();
    }
} 

Finally, handle success response to include location.href which will redirect to controller returning FileResult to download CSV file:

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

As an option, you could pass CSV file name as parameter from AJAX response using query string.

Related issue:

Creating a byte array from a stream

本文标签: javascriptDownload a file through ajax request in aspnet MVCStack Overflow