1

I have a tag object that is loaded dinamically by javascript. This tag is loaded after a jquery post:

$.post('@Url.Action("ShowCredential", "ManageCredentials")',  
    $(form).serialize(), function(url) { 
    document.getElementById("credential_preview").innerHTML = "<object id='credencial_atual' type='application/pdf' classid='clsid:CA8A9780-280D-11CF-A24D-444553540000' width='250' height='420' style='border: 1px solid'> <param name='src' value='" + url + "#navpanes=0&scrollbar=0&zoom=100%' /></object>"; 

    $("#preview_popup").show(); 
}); 

Obs: i load the form variable with my form.

In my code-behind of the action "ShowCredential" i load a pdf in byte[] and store in my user session:

[HttpPost] 
public string ShowCredential(/* the attributes to help to load the pdf */) 
{ 
    // Loading my pdf... 
    Session.User.CurrentPDF = // set the pdf loaded 

    UrlHelper urlHelper = new UrlHelper(this.ControllerContext.RequestContext); 
    string url = urlHelper.Action("GetPDF", "ManageCredentials"); 

    return url; 
}

The url is generated with the action that will return the pdf.

[HttpGet] 
public FileResult GetPDF() 
{ 
    return File(Session.User.CurrentPDF, "application/pdf"); 
} 

So, in the first time, ok, is loaded the right pdf, but in the second, third... is loaded the same pdf, why? (i checked if i pass the right params, yes i pass =))

Obs: When i post the data to load the pdf, after - in jquery return - my code call the action GetPDF in the first time, but, when i post again, the action GetPDF is not called anymore.

Vinicius Ottoni
  • 4,631
  • 9
  • 42
  • 64

3 Answers3

1

Vinicius,

Hopefully the following will help you. In one of my apps I have to display either a word doc, a pdf, an image or any other type of doc. I appreciate that this isn't requested via ajax per se, but may allow you to think of an alternative solution. The following code achieves this (ignore the object model and instead examine the switch statement in particular):

public ActionResult DownloadFile(int fileID, int propertyId)
{
    var item = _tasks.GetByKey(fileID);

    if (item.PropertyEntity.PropertyID == propertyId)
    {
        string docType = item.FileName.Substring(item.FileName.IndexOf(".") + 1);
        switch (docType.ToLower())
        {
            case "doc":
                docType = "application/msword";
                break;
            case "jpg":
                docType = "image/jpeg";
                break;
            default:
                // i.e. do nothing else - this may change
                docType = "application/" + docType;
                break;
        }

        string doc = item.DocumentLocation.Replace("..", "~");
        return File(doc, docType);
    }
    else
    {
        return View("NotFound");
    }
}

Of course, the result isn't displayed inside the view, as the appropriate 'app' is required to display each, thus Adobe PDFReader would be opened in your case.

jim tollan
  • 22,305
  • 4
  • 49
  • 63
  • Yeah. I used this approach. But the "user requirement" is to show the pdf in a div or iframe, as part of the page, not the entire page, you know? – Vinicius Ottoni Feb 09 '12 at 14:02
  • sure - i understand. oh well, back to the drawing board!! :( – jim tollan Feb 09 '12 at 14:06
  • I'm looking for the same in another forum, ´so, look to this answer of vladnech: http://forums.asp.net/t/1767439.aspx/1?How+to+show+a+pdf+returned+by+stream+in+a+JsonResult+ if really is not possible, we have to use ActionResult. =( – Vinicius Ottoni Feb 09 '12 at 14:17
  • i think this may well end up being your only recourse i'm afraid – jim tollan Feb 09 '12 at 14:26
1

Your code seems weird. You are sending a POST AJAX request to some controller action but you don't seem to be doing anything in the success callback with the result (dados variable). Also you seem to be calling the VisualizarCredencial action twice: once for the AJAX request and once for rendering the PDF.

You haven't explained your intentions so I can only be guessing what you are trying to do, and my guess is that you could have 2 controller actions: once that returns the url or an id that could be used to query the second controller action that will return the pdf.

Like this:

[HttpPost]
public ActionResult VisualizarCredencial()
{
    // some id of the pdf
    return Json(new { url = Url.Action("GetPdf", "GerenciarCredenciais", new { id = "123" }) });
}

public ActionResult GetPdf(int id)
{
    byte[] pdf = ... 
    return File(pdf, "application/pdf");
}

and now on the client you could use an iframe:

var url = '@Url.Action("VisualizarCredencial", "GerenciarCredenciais")';
$.post(url, function(result) {
    $('#preview_credencial').html(
        $('<iframe/>', {
            'class': 'pdfpreview', // some CSS class to set the width and height of the preview iframe
            'src': result.url
        })
    );
});

and to avoid potential caching problems with the GepPdf action you could decorate it with a custom [NoCache] action filter.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I try it, look to my new question, and my new problem: http://stackoverflow.com/questions/9217907/my-asp-net-httpget-action-is-only-called-once-in-the-src-of-a-object-tag-after-a – Vinicius Ottoni Feb 10 '12 at 12:30
  • @ViniciusOttoni, your new question seems like a dupe to this one. You should have updated this one with the additional information instead of posting the same question once again. Anyway, you could try the ` – Darin Dimitrov Feb 10 '12 at 12:35
  • Ok, no problem. I 'll try with the iframe and NoCache. And which question you will close? Because in the second one the question is more complete. – Vinicius Ottoni Feb 10 '12 at 12:39
  • @ViniciusOttoni, I voted to close the more recent one. So go ahead and update your original question here to include this additional information. – Darin Dimitrov Feb 10 '12 at 12:41
  • I made a few changes and i 'll update you answer to match with my new question, but the NoCache attribute solve my problem. – Vinicius Ottoni Feb 10 '12 at 13:00
  • @ViniciusOttoni, great, feel free to directly update my answer. – Darin Dimitrov Feb 10 '12 at 13:02
  • I think that you have to change only the begining of your answer because it is related to previous question. ^^ – Vinicius Ottoni Feb 10 '12 at 13:16
0

Looking for the answer, i reach the following conclusion: so, if we use a form.submit() then the controller just return a file result. If we use ajax to pass the data, we cannot return the pdf, but must return something you pass on a get (for exemple href) that will return the pdf.

Vinicius Ottoni
  • 4,631
  • 9
  • 42
  • 64