How to Open PDF File in a New Tab or Window Instead of Downloading It (Using ASP.NET)

How to open PDF file in a new tab or window instead of downloading it using C# and ASP.NET MVC?

The most important thing is Controller.File() works with [HttpGet], hence you should do these steps:

1) Change HTTP method type from [HttpPost] to [HttpGet] and set return File() without specifying fileDownloadName parameter (using overload of Controller.File() which accepts 2 parameters).

[HttpGet]
public virtual ActionResult PdfInvoice(int customerOrderselectedId)
{
var customerOrder = _customerOrderService.GetCustomerOrderById(customerOrderselectedId);

var customerOrders = new List<DD_CustomerOrder>();

customerOrders.Add(customerOrder);
byte[] bytes;
using (var stream = new MemoryStream())
{
_customerOrderPdfService.PrintInvoicePdf(stream, customerOrders);
bytes = stream.ToArray();
}

// use 2 parameters
return File(bytes, MimeTypes.ApplicationPdf);
}

2) Handle click event of that button (preferred using <input type="button" .../>) and use _blank option, or use an anchor tag (<a>) with target='_blank' attribute:

$('#createdata').click(function (e) {
// if using type="submit", this is mandatory
e.preventDefault();

window.open('@Url.Action("PdfInvoice", "ControllerName", new { customerOrderselectedId = selectedId })', '_blank');
});

The reason why fileDownloadName parameter is not used here is that parameter sets Content-Disposition: attachment while file name is provided, otherwise if you're omit it or using null value, then Content-Disposition: inline will be set automatically.

Note that because you're using FileResult, you should not setting Content-Disposition using Response.AddHeader before return File() like this, because doing so will sent multiple Content-Disposition headers which causing browser to not display the file:

// this is wrong way, should not be used
Response.AddHeader("Content-Disposition", "inline; filename=order_XXX.pdf");
return File(bytes, MimeTypes.ApplicationPdf);

Related issues:

How To Open PDF File In New Tab In MVC Using C#

ASP.NET MVC: How can I get the browser to open and display a PDF instead of displaying a download prompt?

Stream file using ASP.NET MVC FileContentResult in a browser with a name?

MVC.Net Open a file in a new window instead of downloading

Found the answer.

2 things have to be done for the file to open in a new window -

1.content-disposition must be set to inline

2.the content type should be set to the type corresponding to the file being downloaded -

application/pdf - for pdf files

application/xml - for xml files

application/vnd.ms-excel - for xls files and so on.

How to open pdf file in new tab Asp.net

You'll have to call window.open('LoadSheet.aspx'), I use it most of the time:

Page.ClientScript.RegisterStartupScript(typeof(Page), "MessagePopUp", "alert('Transaction completed successfully'); window.open('LoadSheet.aspx');", true);

Edit:

My approach is call a Generic Handler (ashx) and do all the job there, passing data through session variables.

VB.Net:

System.Web.UI.ScriptManager.RegisterClientScriptBlock(Me, Me.[GetType](), "myFunction", "window.open('ViewDocument.ashx');", True)

UPDATE:

I created a sample solution using Page.ClientScript.RegisterStartupScript(...) and an .ashx Generic Handler:

MyPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>Show me the PDF in another tab and alert me!</div>
<asp:Button ID="btnShow" runat="server" Text="Show me!" OnClick="btnShow_Click" />
</form>
</body>
</html>

MyPage.aspx.cs (code behind):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnShow_Click(object sender, EventArgs e)
{
// Pass some data to the ashx handler.
Session["myData"] = "This is my data.";

// Open PDF in new window and show alert.
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "Alert", "window.open('ShowPDF.ashx'); alert('OK' );", true);
}
}

ShowPDF.ashx (Generic Handler):

<%@ WebHandler Language="C#" Class="ShowPDF" %>

using System;
using System.Web;
using System.Web.SessionState; // Added manually.
using System.IO; // Added manually.

// You'll have to add 'IReadOnlySessionState' manually.
public class ShowPDF : IHttpHandler, IReadOnlySessionState {

public void ProcessRequest (HttpContext context) {
// Do your PDF proccessing here.
context.Response.Clear();
context.Response.ContentType = "application/pdf";
string filePath = System.Web.HttpContext.Current.Server.MapPath(@"~\docs\sample.pdf");
context.Response.TransmitFile(filePath);

// Show the passed data from the code behind. It might be handy in the future to pass some parameters and not expose then on url, for database updating, etc.
context.Response.Write(context.Session["myData"].ToString());
}

public bool IsReusable {
get {
return false;
}
}

}

Final result:
(Animated GIF. It delays 3 to 5 seconds to start because I couldn't trim it)

Sample Image

QUICK EDIT:

If you're able to response the pdf's content then you can do it at the ashx file:

Pass the sb variable to the ashx. In your code behind:

Session["sb"] = sb;

At your handler:

<%@ WebHandler Language="C#" Class="ShowPDF" %>

using System;
using System.Web;
using System.Web.SessionState; // Added manually.
using System.IO; // Added manually.
/* IMPORT YOUR PDF'S LIBRARIES HERE */

// You'll have to add 'IReadOnlySessionState' manually.
public class ShowPDF : IHttpHandler, IReadOnlySessionState {

public void ProcessRequest (HttpContext context) {
// Do your PDF proccessing here.

// Get sb from the session variable.
string sb = context.Session["sb"].ToString();

//Export HTML String as PDF.
StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
Response.ContentType = "application/pdf";

Response.End();

}

public bool IsReusable {
get {
return false;
}
}

}

I'm in a hurry so this is all I could do.

ULTIMATE EDIT

Modify your current code behind:

using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(sw))
{
StringBuilder sb = new StringBuilder();

//Generate Invoice (Bill) Header.

/***
ALL THE STRING BUILDER STUFF OMITED FOR BREVITY

...
***/

// Pass the sb variable to the new ASPX webform.
Session["sb"] = sb;

// Open the form in new window and show the alert.
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "Alert", "window.open('NewForm.aspx'); alert('Your message here' );", true);

GridView1.AllowPaging = false;
GridView1.DataBind();
}
}

And add a new ASPX file where you will do your PDF process, you should not have trouble with sessions and libraries.

NewForm.aspx

protected void Page_Load(object sender, EventArgs e)
{
// Get sb from the session variable.
string sb = Session["sb"].ToString();

//Export HTML String as PDF.
StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);

PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);

pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();

Response.ContentType = "application/pdf";
Response.End();
}

open generated pdf file in new tab instead of downloading..Web API

Aside from David Mkheyan's proposal of setting the proper MIME type, you also need to change the content disposition from attachment to inline.

result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue(System.Net.Mime.DispositionTypeNames.Inline)
{
FileName = "file.pdf"
};

According to https://www.iana.org/assignments/cont-disp/cont-disp.xhtml attachment means "user controlled display" and inline is "displayed automatically".

ASP.NET Core How to open PDF in a new tab?

_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

ASP open PDF in reading mode inside browser instead of showing download prompt

Looks like you need to return a FileStreamResult e.g.

Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")

From SO here

or you can try FileResult e.g.

return File(fileArray, contentType, fileName)

From SO here

Open PDF in browser instead of downloading it

From what you're experiencing, it seems to me that Composite have gotten the MIME type of your uploaded file wrong, and is therefor not correctly telling the browser that this file is a pdf, and the browser doesn't know what to do with it.

  1. Try deleting the file and uploading it again.
  2. Try add ?download=false and the end of the href to the file. You prob. need to go into source mode of the content editor.

This is the exact line in the Source Code which is responsible for this behavior, and the logic is as follows

  • If there is no Querystring named download, the attachment is determined by the Mime Type. Only png, gif and jpeg will be shown inline, the rest will be shown as attachment.
  • If there is a Querystring named download with a value of false, it will override the Mime Type check and always force the Content-Disposition to be inline.

I made a quick test here to show that the behaviour is a expected. At least in my Chrome browser in Windows 8

  • Force download: https://www.dokument24.dk/media/9fdd29da-dde8-41f7-ba4c-1117059fdf06/z8srMQ/test/Prisblad%202015%20inkl%20moms.pdf
  • Show in browser: https://www.dokument24.dk/media/9fdd29da-dde8-41f7-ba4c-1117059fdf06/z8srMQ/test/Prisblad%202015%20inkl%20moms.pdf?download=false


Related Topics



Leave a reply



Submit