How to download file via $ .ajax ()

1

This question arose from this post Sending data to an ActionResult from a different Controller from the current one answered by James S , I currently have this ActionResult that downloads file through a Post in a View and need to do through $ .ajax ():

 $(document).ready(function () {         
        $(document).on('click', '.lnkEnviarDados', function (e) {
            e.preventDefault();

            var _Atributo_1 = $(this).attr("data-Atributo_1");
            var _Atributo_2 = $(this).attr("data-Atributo_2");
            var _Atributo_3 = $(this).attr("data-Atributo_3");

            $.ajax({
                url:'@Url.Action("BaixarConta","BaixarConta"),
                method:'post',
                data:{_Atributo_1:_Atributo_1 ,_Atributo_2:_Atributo_2,_Atributo_3:_Atributo_3}
                success:function(retorno){

                });


        });
    }

The problem is that the download does not run and I believe the call is made by JQuery.

Below is ActionResult:

[HttpPost]
public ActionResult BaixarConta(int _Atributo_1, int _Atributo_2, int _Atributo_3)
{
     //faço o processamento do arquivo a ser baixado
     var pdf = pechkin.Convert(new ObjectConfig()
                                         .SetLoadImages(true).SetZoomFactor(1.5)
                                         .SetPrintBackground(true)
                                         .SetScreenMediaType(true)
                                         .SetCreateExternalLinks(true)
                                         .SetIntelligentShrinking(true).SetCreateInternalLinks(true)
                                         .SetAllowLocalContent(true), _ObterSelecionado.DocumentoHtml.ToString());

                file = new MemoryStream();
                file.Write(pdf, 0, pdf.Length);
                byte[] arquivo = pdf;
                MemoryStream pdfStream = new MemoryStream();
                pdfStream.Write(arquivo.ToArray(), 0, arquivo.ToArray().Length);
                pdfStream.Position = 0;
     return new FileStreamResult(pdfStream, "application/pdf");
}
  

Here I implemented the James S suggestion

  [HttpGet]
            public ActionResult Download(string file)
            {             
                 string handle = Guid.NewGuid().ToString();
                 var pdfStream = TempData[file]; 
                return  File((byte[])pdfStream, "application/pdf"); //fazendo uma lteração aqui nessa linha pois estava dando erro de conversão
            }
  The problem is that it always returns null in the string file parameter.

In View I added only new { target="_blank"} to open in a new browser tab.

On Controller I have adapted

#region :: Converte o atributo DocumentoHTML em tipo PDF ::
                    var pdf = pechkin.Convert(new ObjectConfig()
                                             .SetLoadImages(true).SetZoomFactor(1.5)
                                             .SetPrintBackground(true)
                                             .SetScreenMediaType(true)
                                             .SetCreateExternalLinks(true)
                                             .SetIntelligentShrinking(true).SetCreateInternalLinks(true)
                                             .SetAllowLocalContent(true), _ObterSelecionado.DocumentoHtml.ToString());

                    file = new MemoryStream();
                    file.Write(pdf, 0, pdf.Length);
                    byte[] arquivo = pdf;
                    MemoryStream pdfStream = new MemoryStream();
                    pdfStream.Write(arquivo.ToArray(), 0, arquivo.ToArray().Length);
                    pdfStream.Position = 0;

                    ///Aqui alterei conforme sugestão do Tiago S
                    string handle = Guid.NewGuid().ToString();
                    TempData[handle] = pdfStream;
                    return Json(new { FileGuid = handle });

                    #endregion
    
asked by anonymous 11.06.2017 / 19:10

1 answer

1

One solution would be to generate a temporary download link and make a GET request

Instead of returning a FileStreamResult, you return a Json with a

[HttpPost]
public ActionResult BaixarConta(int _Atributo_1, int _Atributo_2, int _Atributo_3)
{
     //faço o processamento do arquivo a ser baixado
     string handle=Guid.NewGuid().ToString();
     TempData[handle]=pdfStream;

     return Json( new { FileGuid = handle});
}

This key you use in ajax to generate the link

In your Ajax

   $.ajax({
            url:'@Url.Action("BaixarConta","BaixarConta"),
            method:'post',
            data:{_Atributo_1:_Atributo_1 ,_Atributo_2:_Atributo_2,_Atributo_3:_Atributo_3}
            success:function(retorno){
                window.location='@Url.Action("Download","BaixarConta")?file='+retorno.FileGuid;
            }
    });

Action Download

[HttpGet]
public ActionResult Download(string file)
{
     //faço o processamento do arquivo a ser baixado
     string handle=Guid.NewGuid().ToString();
     var pdfStream= TempData[file];

     return  File(pdfStream, "application/pdf");
}
    
11.06.2017 / 19:32