2

In my controller I have the following action to create a PDF

public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID)
        {
            var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
            return File(mailingLabel.NoticeContents, "application/pdf", "MailingLabel.pdf");
        }

And In my view i have the following link,

<a asp-action="ExportMailingLabel" asp-controller="Product" asp-area="Product" asp-route-CustomerID="@Model.CustomerID" asp-route-ProductID="@Model.ProductID" class="btn btn-primary"><i class="fa fa-receipt"></i> View Mailing Label</a>

I need help when on click to open the PDF in a new Tab instead of displaying Open Dialog box.

I tried target="_blank" but i seems like it open a new tab but still shows open dialog box

gurkan
  • 884
  • 4
  • 16
  • 25
Rob
  • 225
  • 5
  • 15
  • Hi @Rob,It depends on the browser settings how the download is handled.I suggest that you could use the Chrome browser. It could open a new tab without displaying open dialog box. – Rena Jul 09 '20 at 02:17
  • Hi @Rena I just tried that, chrome automatically downloads it, Firefox give you an option to save or Open. Thanks! – Rob Jul 09 '20 at 02:32

1 Answers1

2

_target="blank" is a simple HTML tag once for all and I think that it works in all browsers as expected. You can use it with a static or dynamic file name as follows.

STATIC FILE NAME USAGE

Controller.cs

public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID) {
    var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
    return File(mailingLabel.NoticeContents, "application/pdf");//we don't send 3.parameter yet
}

View.cshtml

<a asp-action="ExportMailingLabel"
   asp-controller="Product"
   asp-route-CustomerID="@Model.CustomerID"
   asp-route-ProductID="@Model.ProductID"
   asp-route-FileName="MailingLabel.pdf" class="btn btn-primary" id="btnOpenDocument">
    <i class="fa fa-receipt"></i> View Mailing Label
</a>

@section Scripts
{
    <script>
        //We are opening the file with js instead of action when click to the button
        $('#btnOpenDocument').click(function (e) {
            e.preventDefault();
            window.open('@Url.Action("ExportMailingLabel"
                             ,"Product"
                             ,new {customerId=selectedCustomerId
                                  ,productId=selectedProductId
                                  ,fileName="MailingLabel.pdf" })'
                        ,"_blank");
        });
    </script>
}

DYNAMIC FILE NAME USAGE

Controller.cs

//We are adding a new route to action for file name
[HttpGet("[controller]/[action]/{customerId}/{productId}/{fileName}")]
public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID) {
    var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
    return File(mailingLabel.NoticeContents, "application/pdf", $"{CustomerID}_{ProductID}.pdf");        
}

View.cshtml

<a asp-action="ExportMailingLabel"
   asp-controller="Product"
   asp-route-CustomerID="@Model.CustomerID"
   asp-route-ProductID="@Model.ProductID"
   asp-route-FileName="@(Model.CustomerID)_@(Model.ProductID).pdf" class="btn btn-primary" id="btnOpenDocument">
    <i class="fa fa-receipt"></i> View Mailing Label
</a>

@section Scripts
{
    <script>
        //We are opening the file with js instead of action when click to the button
        $('#btnOpenDocument').click(function (e) {
            e.preventDefault();
            window.open('@Url.Action("ExportMailingLabel"
                             ,"Product"
                             ,new {customerId=selectedCustomerId
                                  ,productId=selectedProductId
                                  ,fileName=selectedCustomerId+"_"+selectedProductId+".pdf" })'
                        ,"_blank");
        });
    </script>
}

FileContentResult Class

gurkan
  • 884
  • 4
  • 16
  • 25
  • Is there any way to set the file name in this case? I tried this and it worked, but the filename is just the controller method name, which isn't what I want the file to be called. – trademark Apr 05 '21 at 18:04
  • @trademark Yes you are right. I added another rows to the content of post after your question. You can use it from _DYNAMIC USAGE_ header – gurkan Apr 06 '21 at 12:55
  • Maybe I'm missing something, but doesn't adding that third parameter cause the file to just download instead of opening in browser? I've read that using that parameter sets the Content-Disposition to "attachment" and that makes the browser download it. https://stackoverflow.com/a/54996397/5354201 – trademark Apr 06 '21 at 13:32
  • @trademark I didn't examine the parameters before but I took a look just now. You can see it from [here](https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ControllerBase.cs#L1143) and example [here](https://github.com/dotnet/aspnetcore/blob/5b8561499bfad98a7f3c5d69720ae560de2d38cb/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DownloadPersonalData.cshtml.cs#L82). You can add a header for dispositon but it's is already [`inline`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition). I didn't need to mention because SO was not related it. – gurkan Apr 06 '21 at 14:11