ASP.NET MVC - Download PDF file in same window not working - javascript

I have download PDF file(not to open) generated from controller method. file is getting opened in new separate window. I am generating MemoryStream at server side. I have to return it to client in same window, here I don't have to open, just download in the same client window.
below code I have tried -
Server-
public async Task<ActionResult> DownloadReport(string id, string reportType="")
{
var fileData = await GetReport(id, reportType);
// here fileData is MemoryStream
return File(fileData, "application/pdf");
}
html code -
#Html.ActionLink("Download", "DownloadReport","Files", new { id = "abc" },null)

Use Content-Disposition header
public async Task<ActionResult> DownloadReport(string id, string reportType="")
{
var fileData = await GetReport(id, reportType);
// here fileData is MemoryStream
Response.AddHeader("Content-Disposition", "attachment;filename=file.pdf");
return File(fileData, "application/pdf");
}

Related

how to handle respond of fileResult in Javascript

The controller:
[HttpGet]
public FileResult Get()
{
//execute sql
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt, "file");
using (MemoryStream stream = new MemoryStream())
{
wb.SaveAs(stream);
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Data.xlsx");
}
}
}
how i handle this to javascript to download it from page?
How about calling the fileresult url in a new page? Like;
window.open("/FileController/Get");
Browser will detect the FileResult and download will start.

Upload a file to byte array in MySQL successfully, however the content is not readable when download

I am having a problem when downloading the content after I uploaded the file using FormData in JavaScript XMLHttpRequest and connect to Web API and save it to MySQL DB as LONGBLOB data type. When I tried to download the file that is being uploaded previously as BLOB to MySQL DB, the file is being downloaded, however the file cannot be readable anymore. Any solutions?
Here is the code that I am using for uploading the file to the DB as byte array:
HTML and Javascript:
<input id="Upload" type="file" accept="application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf" />
let SubmittedData = new FormData();
let XHR = new XMLHttpRequest();
SubmittedData.append("FileContent", $("#Upload").files[0]);
XHR.open("POST", "/UploadFile");
XHR.send(SubmittedData);
XHR.onreadystatechange = function () {
if (XHR.readyState == 4 && XHR.status == 200)
alert("Success");
}
Web API:
[HttpPost]
public ActionResult UploadFile()
{
if (Request.Files.Count <= 0)
return Ok();
byte[] FileContent = new byte[0];
using (var reader = new BinaryReader(Request.Files[0].InputStream))
FileContent = reader.ReadBytes(Request.Files[0].ContentLength);
InsertToMySQLDB(FileContent);
return Ok()
}
Here is the code that I am using for retrieve the byte array from DB and download it as PDF (I am using HtmlToPDF library in NuGet for downloading as PDF) and Word:
public ActionResult DownloadPDF()
{
byte[] FileContent = RetrieveFileContentFromMySQLDB();
return File(FileContent, "application/pdf", "File.pdf");
}
public ActionResult DownloadWord()
{
byte[] FileContent = RetrieveFileContentFromMySQLDB();
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Disposition", $"attachment;filename=File.doc");
Response.Charset = string.Empty;
Response.ContentType = "application/vnd.ms-word";
Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
Response.Flush();
Response.End();
break;
)
EDIT:
There is another problem now, the scenario is:
When I upload the PDF file and download it as PDF, it can be downloaded and the content is same like what I have been uploaded before, however when I tried to download it as Word, it is being downloaded, but the content is just all hex characters.
When I upload the Word file and download it as PDF, it cannot be downloaded (the file is corrupted), and when I download it as Word, it is being downloaded, but the content is just all hex characters.
Any solutions for the conversion?
Thank you very much
I think you can change DownloadPDF() to :
public ActionResult DownloadPDF()
{
byte[] FileContent = RetrieveFileContentFromMySQLDB();
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Disposition", $"attachment;filename=File.pdf");
Response.Charset = string.Empty;
Response.ContentType = "application/pdf";
Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
Response.Flush();
Response.End();
break;
}
Above is (almost) the same as DownloadWord(). The differences are the headers "Content-Disposition" and "Content-Type".

How can I open a PDF file in new tab without saving this file using ASP.NET MVC 5? [duplicate]

I would like to view a PDF file directly in my browser. I know this question is already asked but I haven't found a solution that works for me.
Here is my action's controller code so far:
public ActionResult GetPdf(string fileName)
{
string filePath = "~/Content/files/" + fileName;
return File(filePath, "application/pdf", fileName);
}
Here is my view:
#{
doc = "Mode_d'emploi.pdf";
}
<p>#Html.ActionLink(UserResource.DocumentationLink, "GetPdf", "General", new { fileName = doc }, null)</p>
When I mouse hover the link here is the link:
The problem with my code is that the pdf file is not viewed in the browser but I get a message asking me if I wand to open or save the file.
I know it is possible and my browser support it because I already test it with another website allowing me to view pdf directly in my browser.
For example, here is the link when I mouse hover a link (on another website):
As you can see there is a difference in the generated link. I don't know if this is useful.
Any idea how can I view my pdf directly in the browser?
The reason you're getting a message asking you to open or save the file is that you're specifying a filename. If you don't specify the filename the PDF file will be opened in your browser.
So, all you need to do is to change your action to this:
public ActionResult GetPdf(string fileName)
{
string filePath = "~/Content/files/" + fileName;
return File(filePath, "application/pdf");
}
Or, if you need to specify a filename you'll have to do it this way:
public ActionResult GetPdf(string fileName)
{
string filePath = "~/Content/files/" + fileName;
Response.AddHeader("Content-Disposition", "inline; filename=" + fileName);
return File(filePath, "application/pdf");
}
Instead of returning a File, try returning a FileStreamResult
public ActionResult GetPdf(string fileName)
{
var fileStream = new FileStream("~/Content/files/" + fileName,
FileMode.Open,
FileAccess.Read
);
var fsResult = new FileStreamResult(fileStream, "application/pdf");
return fsResult;
}
Change your code to this :
Response.AppendHeader("Content-Disposition","inline;filename=xxxx.pdf");
return File(filePath, "application/pdf");
If you read the file stored in database image column, you can use like this:
public ActionResult DownloadFile(int id)
{
using (var db = new DbContext())
{
var data =
db.Documents.FirstOrDefault(m => m.ID == id);
if (data == null) return HttpNotFound();
Response.AppendHeader("content-disposition", "inline; filename=filename.pdf");
return new FileStreamResult(new MemoryStream(data.Fisier.ToArray()), "application/pdf");
}
}
If you are using Rotativa package to generate PDF, Then don't put a name to file with FileName attribute like below example.
return new PartialViewAsPdf("_JcPdfGenerator", pdfModel);
Hope this is helpful to someone.
Although previous posts are often correct; I think most of them are not best practice!
I'd like to suggest to change action return types to FileContentResult and usereturn new FileContentResult(fileContent, "application/pdf"); at the end of action body.
Yes You Can do It Simply by redirecting . it ends extension like u need , .pdf ..
protected void OpenPdfPdf_Click(object sender, EventArgs e)
{
Response.Redirect("jun.pdf");
}
Or another Method ,its opens like .aspx page--
protected void OpenPdf_Click(object sender, EventArgs e)
{
string path = Server.MapPath("jun.pdf");
//or you want to load from url change path to
//string path="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(path);
if (buffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", buffer.Length.ToString());
Response.BinaryWrite(buffer);
}
}

Downloading a file in MVC app using AngularJS and $http.post

Any help is most welcomed and really appreciated.
I have an MVC action which retries a file content from a web service. This action is invoked from a Angular service (located in services.js) using $http.post(action, model), and the action is returning a FileContentResult object, which contains the byte array and the content type.
public ActionResult DownloadResults(DownloadResultsModel downloadResultsModel)
{
downloadResult = ... // Retrieving the file from a web service
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", downloadResult.FileName));
Response.BufferOutput = false;
return new FileContentResult(downloadResult.Contents, downloadResult.ContentType);
}
The issue I'm having is about the browser not performing the default behavior of handing a file (for example, prompting to open it, saving it or cancel). The action is completed successfully with having the content of the file and the file name (injected to the FileContentResult object), but there s no response from the browser.
When I'm replacing the post with $window.location.href, and construct the URI myself, I'm hitting the action and after it completes the browser is handling the file as expected.
Does anyone can think of any idea how to complete the 'post' as expected?
Thanks,
Elad
I am using below code to download the file, given that the file does exist on the server and client is sending server the full path of the file...
as per you requirement change the code to specify path on server itself.
[HttpGet]
public HttpResponseMessage DownloadFile(string filename)
{
filename = filename.Replace("\\\\", "\\").Replace("'", "").Replace("\"", "");
if (!char.IsLetter(filename[0]))
{
filename = filename.Substring(2);
}
var fileinfo = new FileInfo(filename);
if (!fileinfo.Exists)
{
throw new FileNotFoundException(fileinfo.Name);
}
try
{
var excelData = File.ReadAllBytes(filename);
var result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(excelData);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileinfo.Name
};
return result;
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.ExpectationFailed, ex);
}
}
and then on client side in angular:
var downloadFile = function (filename) {
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.src = document.location.pathname + "api/GridApi/DownloadFile?filename='" + escape(filename) + "'";
ifr.onload = function () {
document.body.removeChild(ifr);
ifr = null;
};
};

ashx page opens in excel instead of document retrieved

I have links that call a javascript function "GetDocument" which passes the ID of the link that the user wants to retrieve to an ashx page which than retrieves the document from a database and writes it back to the users browser if it's a PDF or opens the appropriate program if it's something else. These could be PDF's, XLS, DOCX.... etc.. When the user clicks a link that is a PDF everything work just fine and the PDF is opened within the browser. When the user opens anything else though, lets say for example an xlsx excel opens a garbage file with the name of the .ashx page. No errors occur and everything works with PDF. I'm kind of at a loss.
Here is the javascript
function GetDocument(id) {
spl1.loadPage('RightContent', 'FrmDocHandler.ashx?ID=' + id);
}
Here is the .ashx page
Public Class FrmDocHandler
Implements System.Web.IHttpHandler
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sID As String = context.Request.QueryString("id")
Dim fileName As String = String.Empty
Dim fileType As String = String.Empty
Dim bytes() As Byte
bytes = Get_Blob(fileName, fileType, sSql_GetDocument(sID))
context.Response.Clear()
'clear the content of the browser
context.Response.ClearContent()
context.Response.ClearHeaders()
context.Response.Buffer = True
'I tried both of these add header and the same result
'context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
context.Response.AddHeader("Content-Disposition", "inline; filename=" + fileName)
context.Response.ContentType = GetMIMEType(fileType)
context.Response.BinaryWrite(bytes)
End Sub
MIME Types returned by GetMIMEType
Public Const g_MIME_DOC As String = "application/msword"
Public Const g_MIME_DOCX As String = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
Public Const g_MIME_DOT As String = "application/msword"
Public Const g_MIME_DOTX As String = "application/vnd.openxmlformats-officedocument.wordprocessingml.template"
Public Const g_MIME_HTM As String = "text/html"
Public Const g_MIME_HTML As String = "text/html"
Public Const g_MIME_JPEG As String = "image/jpeg"
Public Const g_MIME_PDF As String = "application/pdf"
Public Const g_MIME_PPSX As String = "application/vnd.openxmlformats-officedocument.presentationml.slideshow"
Public Const g_MIME_PPT As String = "application/vnd.ms-powerpoint"
Public Const g_MIME_PPTX As String = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
Public Const g_MIME_XLS As String = "application/vnd.ms-excel"
Public Const g_MIME_XLSX As String = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Public Const g_MIME_XLTX As String = "application/vnd.openxmlformats-officedocument.spreadsheetml.template"
Public Const g_MIME_XML As String = "application/rss+xml"
The line which is probably causing the file to be opened in Excel is the following:
context.Response.ContentType = GetMIMEType(fileType)
A couple of things you can do:
Check to see what MIME type is being returned by GetMIMEType, and ensure its a PDF related one (application/pdf) rather than an Excel related one (application/vnd.ms-excel)
Check on the browser end to see what application is set to handle the mime type and/or file extension that you are sending from the server

Categories

Resources