How to download file via $.ajax()

Asked

Viewed 2,388 times

2

This doubt arose from this post Send data to an Actionresult from a Controller other than the current one answered by Tiago S, currently have this ActionResult that downloads file through a Post in a View and needs 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 that the call is made by Jquery.

Below is the 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 suggestion of Tiago S

  [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 always returns null in the parameter string file.

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

In the Controller I adapted it

#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

1 answer

1


A 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 key

[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");
}
  • Thanks @Tiago S on action Download always returns null, I spent some time trying to identify why rs and do not know more what to do rs I edited the question and added more details, since I thank you or anyone else who can help.

  • You say this call window.location='@Url.Action("Download","BaixarConta")?file='+retorno.FileGuid when it comes to the controller and the method Download is coming null the file parameter, that’s it?

  • That’s right @Tiaho S

  • Once I had trouble with that, in this case you add a / before the ?file being like this window.location='@Url.Action("Download","BaixarConta")/?file=‌​'+retorno.FileGuid

  • Adding the bar works yes, but I had to take the new { {target='_blank'} of @Utl.Action and now I have another problem, because the system screen closes instead of opening a new browser tab for this pdf.

  • In place of windows.location utilize windows.open() in your case gets like this: window.open( '@Url.Action("Download","BaixarConta")/?file‌​=‌​'+retorno.FileGui‌​d,&#xA; '_blank' // <- This is what makes it open in a new window.&#xA;);

  • 1

    Very good! Congratulations ! Thanks @Tiago S, it worked!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.