ASP.NET MVC download prompt not appearing - asp.net-mvc

I'm trying to generate a Excel .xlsx file in a controller action. I would like to have the website show a download prompt to download the resulting file. The controller actions executes fine, but no download prompt is shown. Nothing happens.
I've tried:
MemoryStream mstream = ... //generated file;
return File(mstream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", model.DisplayName + ".xlsx");
I've tried:
return new FileStreamResult(mstream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = model.DisplayName + ".xlsx" };
I've tried:
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + model.DisplayName + ".xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Write(mstream.ToArray());
Response.End();
return Content("");
I even tried saving the file to disk, then returning via the filepath
return File(filepath, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
What am I doing wrong?
Thanks!

I am using the following code in an MVC project.
public ActionResult GetCSV()
{
string filename = "example";
string csv = MyHelper.GetCSVString();
return File(Encoding.UTF8.GetBytes(csv.ToString()), "text/csv", string.Format("{0}.csv", filename));
}
My csv string could look something like this
"Col1,Col2,Col3\nRow1Val1,Row1Val2,Row1Val3\n"
To trigger this download in a new window I call the following JavaScript
window.open('/MyUrl/GetCSV', 'DownloadWindowName');

Add the header as follows.
var cd = new System.Net.Mime.ContentDisposition
{
FileName = model.DisplayName + ".xlsx",
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
then return the file as follows
return File(mstream, ".xlsx");
Regarding download prompt. If you mean a prompt where it asks where to save the file, then it depends on how the user has set it up in their browser settings. For example in chrome, users can choose not to get a prompt when downloading files and have it downloaded to a pre specified location like the download folder.
http://malektips.com/google-chrome-prompt-download-file.html#.VM-DbFWsUm8

Related

How to attach a created file to mail mvc

As each user runs through my application I hold their data and dump it into a report as follows, which at the end is created into a pdf document and is later automatically downloaded on the users side(client-side). I now want to attach this document to an email and have it forwarded to them. This is where I have troubles with the attachment.
Code as follows:
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports/PP_RentalAgreement.rpt")));
rd.SetParameterValue("rent_agree_no", _1);
rd.SetParameterValue("r_initial", _2);
rd.SetParameterValue("r_f_name", _3);
rd.SetParameterValue("r_l_name", _4);
rd.SetParameterValue("r_id_no", _5);
rd.SetParameterValue("r_lic_no", _6);
rd.SetParameterValue("r_tel", _7);
rd.SetParameterValue("r_cell", _8);
rd.SetParameterValue("r_fax", _9);
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream st = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
st.Seek(0, SeekOrigin.Begin);
if (ModelState.IsValid)
{
var m_message = new MailMessage();
m_message.To.Add(new MailAddress("JoeSoap#TextMail.com"));
m_message.Subject = "Pink Panther - Invoice";
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
using (var smtp = new SmtpClient())
{
await smtp.SendMailAsync(m_message);
return RedirectToAction("Index");
}
}
I am getting an error on this line : m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf")); saying The specified content type is invalid.
Someone suggested to me that I should specify a path however I am not actually saving this file anywhere
How am I able to allow the file to be attached and send it to the recipient?
The System.Net.Mail.Attachment class constructor with 3 overloads consist of these parameters:
public Attachment(System.IO.Stream contentStream, string name, string mediaType)
Hence, you're assigning name and content type in reversed order, which causing invalid content type problem at this code:
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
The correct way is putting the file name as second argument like example below:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", "application/pdf"));
Or using MediaTypeNames for content type setting:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", MediaTypeNames.Application.Pdf));

File Download using asp.net mvc

I tried using the below code. But it did not work.
public FileResult download(string path)
{
return File(path, "application/pdf", Server.UrlEncode(path));
}
My Ajax Code is:
function fileDownload(path) {
$.ajax({
url: '/Home/download',
data: { path: path },
type: 'POST',
async: false,
success: function (data) { }
});
}
You'll generally want to map the file name to a physical path on the server, e.g. assuming the user selects the file Foo.pdf and all content files are in the ~/Content folder:
public FileResult download(string path)
{
string actualPath = Server.MapPath("~/Content/" + path);
return File(actualPath, "application/pdf", Server.UrlEncode(path));
}
However, from a security viewpoint, allowing a user to directly specify a file name is dubious - you may instead want to consider other alternatives, such as a table or dictionary of available files, and force the browser to select one of the available files via key - this way malicious users can't phish for files which weren't meant to be served.
Edit, after seeing that OP wants to Ajax
Ajaxing the document down should work, although downloading in this way won't render the PDF - you would need to pass the document to a scriptable PDF viewer or similar.
Instead of ajaxing the document, you can instead generate a simple link, button or image which the user can click on to invoke the controller action and download the PDF:
#Html.ActionLink("Click to download", "download", new {path = "MyNicePDF.pdf"})
function DownloadAndReturnBackAttachment(linkHref) {
$.fileDownload(linkHref, {
successCallback: function (url) {
gvScanDocuments.PerformCallback();
gvScanDocuments.UnselectRows();
},
failCallback: function (url) {
alert("A file download error has occurred, please try again.");
gvScanDocuments.PerformCallback();
gvScanDocuments.UnselectRows();
}
});
}
This task is complete using window.location method.
Also You can use HTML tag for this:
download me
public FileResult Download(string path)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(path);
string fileName = "your file name";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

How to refresh view after download file in MVC

I am working in MVC. i want to refresh my view after downloading file.
I have tried following code:
Response.Clear()
Response.ClearHeaders()
Response.ClearContent()
Response.AddHeader("Content-Disposition", "attachment; filename=" + "MyFile.txt")
' Response.AddHeader("Target", "_self")
'Response.AddHeader("Content-Length", File.Length.ToString())
Response.ContentType = "text/plain"
Response.Flush()
Dim obytearray = UTF8Encoding.UTF8.GetBytes(pLicenseFile)
Dim ostring = UTF8Encoding.UTF8.GetString(obytearray)
Response.BinaryWrite(obytearray)
Response.[End]()
i want to get response at client side. or Is it possible to download in other tab and get back to my current view?
i have tried Inline in following line:
Response.AddHeader("Content-Disposition", "Inline; filename=" + "MyFile.txt")
But in this case i lost my current view :(
Thanks!

XlsSaveOptions(SaveFormat.Excel97To2003) issue in IE 8

I am generating a report in an MVC project. The user has the option of getting the report in either .pdf format or .xls
I am using Aspose.Cells for the Excel file generation. The ActionResult method below is called.
[HttpGet]
public ActionResult GenerateReport(string format, string filterDate = "")
{
//Processing occurs here to get the appropriate info from Db.
var fileFormat = format.ToUpper() == "PDF" ? Format.Pdf : Format.Csv;
var contentType = fileFormat == Format.Pdf ? "application/pdf" : "application/vnd.ms-excel";
var makePdf = fileFormat == Format.Pdf;
var fileContents = register.GetReport(makePdf, filterDate);
return File(fileContents, contentType, "Report");
}
register.GetReport() merely determines if GetExcelVersion() or GetPdfVersion() is called.
private void GetExcelVersion(MemoryStream stream, string name, string dateRequested = "")
{
var license = new Aspose.Cells.License();
license.SetLicense("Aspose.Total.lic");
var workbook = new Workbook();
var worksheet = workbook.Worksheets[0];
var cells = worksheet.Cells;
//writes out the appropriate information to the excel spreadsheet here
workbook.Save(stream, new XlsSaveOptions(Aspose.Cells.SaveFormat.Excel97To2003));
}
This works a charm in Firefox and IE10 but when testing on IE8 I receive the following alert from Excel:-
The File you are trying to open 'XXXXX', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now? Yes/No
Any ideas on what I am doing wrong?
Cheers!
As Saqib Razzaq mentioned in the comments above. Turn off compatibility mode as mentioned here

How to export pdf report in jasper reports

I want to export a report as pdf and it should ask the user for a download location. How do I do this in grails?
This is my code:
def exportToPdf(JasperPrint jasperPrint,String path,request){
String cur_time =System.currentTimeMillis();
JRExporter pdfExporter = null;
pdfExporter = new JRPdfExporter();
log.debug("exporting to file..."+JasperExportManager.exportReportToPdfFile(jasperPrint, "C:\\pdfReport"+cur_time+".pdf"));
return ;
}
In jasper controller:
/**
* Generate a html response.
*/
def generateResponse = {reportDef ->
if (!reportDef.fileFormat.inline && !reportDef.parameters._inline) {
response.setHeader("Content-disposition", "attachment; filename=\"" + reportDef.name + "." + reportDef.fileFormat.extension + "\"");
response.contentType = reportDef.fileFormat.mimeTyp
response.characterEncoding = "UTF-8"
response.outputStream << reportDef.contentStream.toByteArray()
} else {
render(text: reportDef.contentStream, contentType: reportDef.fileFormat.mimeTyp, encoding: reportDef.parameters.encoding ? reportDef.parameters.encoding : 'UTF-8');
}
}
Have you looked at the Jasper Plugin? It seems to have the tools already built for you. As far as asking the user for a download location the browser has some controller over how files are received from a web page. Is your real issue that you want control over the download location?
[UPDATE]
Using the location 'c:\' is on your server not the client and this is why it is not downloading.
try something like this...
def controllerMethod = {
def temp_file = File.createTempFile("jasperReport",".pdf") //<-- you don't have to use a temp file but don't forget to delete them off the server at some point.
JasperExportManager.exportReportToPdfFile(jasperPrint, temp_file.absolutePath));
response.setContentType("application/pdf") //<-- you'll have to handle this dynamically at some point
response.setHeader("Content-disposition", "attachment;filename=${temp_file.getName()}")
response.outputStream << temp_file.newInputStream() //<-- binary stream copy to client
}
I have not tested this and there are better ways of handling the files and streams but i think you'll get the general idea.

Resources