MVC 4 Export To CSV - Save As dialogue box not working in Chrome and Firefox - asp.net

I am trying Export csv file to the User with Open/Save option.
My issue is some what similar to how-to-force-chrome-to-open-an-open-file-dialog-when-downloading-a-file-via-as(It is downloading the file in Chrome and Firefox), I have tried with the solution suggested by #Dev but it is not working.
I wrote my code as below:-
return File(new System.Text.UTF8Encoding().GetBytes(csvData),
"text/csv", filename);
But, it was not working in Chrome. The file is getting downloaded by default.
Then after googling , I found returning-a-file-to-view-download-in-mvc, from which I was trying to do something like below:-
var csvData = "hello";// I am filling this variable with ,y values from DB!
var cd = new System.Net.Mime.ContentDisposition
{
// for example foo.bak
FileName = "test",
Inline = false,
};
Response.AppendHeader("Content-Disposition",
cd.ToString());
return File(new System.Text.UTF8Encoding().GetBytes(csvData),
"text/csv");
but still it was downloading the file in Chrome. then I came across how-to-display-open-save-dialog-asp-net-mvc-4, where #JoãoSimões mentioned as:-
That is browser dependent. If you set to download automatically to a
given folder, the browser will download automatically. Firefox and
Chrome are some browsers with this behavior. – João Simões Jan 3 at
13:09
If the above is true, then how can I overcome my problem? How can I get the open/save dialogue ?
I am unable to Export my CSV with open/save option.
Edit 1
I was trying to do something like this (got it here):-
public class ExcelResult : ActionResult
{
public string FileName { get; set; }
public string Path { get; set; }
public string Data { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Buffer = true;
context.HttpContext.Response.Clear();
context.HttpContext.Response.AddHeader("content-disposition", "attachment; filename=" + FileName);
context.HttpContext.Response.ContentType = "text/csv";
context.HttpContext.Response.Write(new System.Text.UTF8Encoding().GetBytes(Data));
}
}
and My controller code:-
return new ExcelResult
{
FileName = "sample.xls",
Path = "",
Data = csvData
};
but still, it is downloading the Excel ...
Edit 2
Tried opening the excel with HttpContext.Current.Response
/// <summary>
/// Export CSV
/// </summary>
/// <returns></returns>
public void DownloadCSV()
{
try
{
var csvData = Session["CSVData"].ToString();
byte[] getContent = new System.Text.UTF8Encoding().GetBytes(csvData);
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.Buffer = true;
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
System.Web.HttpContext.Current.Response.AddHeader("Content-Length", getContent.Length.ToString());
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + "testing.csv");
System.Web.HttpContext.Current.Response.BinaryWrite(getContent);
System.Web.HttpContext.Current.Response.Flush();
}
catch (Exception ex)
{
HttpResponseMessage message = new HttpResponseMessage()
{
Content = new StringContent("Error Exporting Data")
};
throw new System.Web.Http.HttpResponseException(message);
}
}
but, still not working!!!

#shubh have you tried How to force Chrome to open an "open file dialog" when downloading a file vía ASP.NET codebehind? second solution they have put image in where they show how to open dialog box in chrome. I have chrome Version 30.0.1599.101 m in that if you go to setting in that advance setting then down you will find check box which was given in above link answer, that will solve your problem I think.
If still not working then might be problem with your browser just update it to latest version then try again.
Edit 1:
If you put your file name extension .xls then it will open in excel for csv you need to put file name as FileName = "sample.csv", then it will open in csv format.
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=GridViewtoCSVExport.csv");
Response.Charset = string.Empty;
Response.ContentType = "application/text";
for more check this http://surajdeshpande.wordpress.com/2013/09/03/export-gridview-data-to-csv-file-in-asp-net/

If the user has configured his browser to automatically download files, there's absolutely nothing you could do on the server to force this dialog to appear. I am afraid that what you are trying to achieve is impossible.

Try to supply another value for your content-disposition header:
Response.AppendHeader("Content-Disposition", "attachment");

Related

Allowing the user downloading a file located in a specific IIS folder

I have the following issue: ASP-MVC
I want to put a file in a folder in IIS and allow users surfing my site to download it.
In my site, I will have a link that points to an action method in my controller, and within this method I want to put the needed code. Never dealt with this issue before, will appriciate a code sample. Thanks!
This code , taken from this question, will accomplish what you want.
public FileResult Download()
{
byte[] fileBytes = System.IO.File.ReadAllBytes("c:\folder\myfile.ext");
string fileName = "myfile.ext";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
Assuming you want to get a specific file based on some passed-in ID, you can use the Controller.File function as described here: http://msdn.microsoft.com/en-us/library/dd492492(v=vs.100).aspx
Here's an example controller function from that page:
public ActionResult ShowFileFN(string id) {
string mp = Server.MapPath("~/Content/" + id);
return File(mp, "text/html");
}
This will return a binary stream of the named file with the specified MIME content type, in this case "text/html". You'll need to know the MIME type for each file you're returning.
Here's a function to get the MIME type of a file based on its extension:
public static string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}

Create Text File in Memory and return it over ajax, possible?

I can create a text file easily enough but I want to avoid having to keep the file on the server.
How can I create a text file in memory and return it over ajax so the file itself is returned and no file is kept on server? It doesn't need to be ajax but I want to avoid a postback if at all possible.
You can use below code to download text file in webforms
MemoryStream ms = new MemoryStream();
TextWriter tw = new StreamWriter(ms);
tw.WriteLine("HELLO WORLD!");
tw.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!");
tw.Flush();
var bytes = ms.GetBuffer();
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=test.txt");
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.ContentType = "text/plain";
Response.BinaryWrite(bytes);
Vijay's answer is correct if you're using either MVC or WebForms.
About preventing postback, You don't have to use ajax to prevent postback.
If you're using MVC, You just have to use window.location and point it to your action method in js. Something like:
// In your controller:
public class HomeController : Controller
{
public FileResult GetFile2(int id)
{
if (SomeCondition)
{
return null;
}
var fileName = "MyResult.txt";
var content = "Here's the result";
var contentType = "text/plain";
return File(Encoding.ASCII.GetBytes(content), contentType, fileName);
}
// And in your view/js file:
window.location.href = ('/Home/GetFile?id=1');
And if you're using webforms, I think best way is to create a HttpHandler to handle download links. A good tutorial can be found here.

How to handle errors when using ASP.NET to create a zipfile for download?

I'm working on a functionality in my asp.net web site that enables the user to download some files as a zip file. I'm using the DotNetZip library to generate the zip file.
My code looks like this:
protected void OkbtnZipExport_OnClickEvent(object sender, EventArgs e)
{
var selectedDocumentIds = GetSelectedDocIds();
string archiveName = String.Format("archive-{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
AddResponseDataForZipFile(Response, archiveName);
try
{
string errorMessage = Utils.ExportToZip(selectedDocumentIds, arkivdelSearchControl.GetbraArkivConnection(), Response.OutputStream);
if (!string.IsNullOrEmpty(errorMessage))
{
LiteralExportStatus.Text = errorMessage;
}
else
LiteralExportStatus.Text = "Success";
}
catch (Exception ex)
{
LiteralExportStatus.Text = "Failure " + ex.Message;
}
Response.Flush();
Response.Close();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
private void AddResponseDataForZipFile(HttpResponse response, string zipName)
{
Response.Clear();
Response.BufferOutput = false;
Response.ContentType = "application/x-zip-compressed";
Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
Response.AddHeader("Expires", "0");
Response.AddHeader("Content-Description", "Zip Arcive");
}
Now, if anything goes wrong, say the Utils.ExportToZip method fails, I want to present an error message to the user and not the download dialog. Do I have to remove some data from the Response object in order to cancel the download operation?
Best regards
OKB
first, Don't call HttpContext.Current.ApplicationInstance.CompleteRequest();
Reference.
At one point, there was some example code that showed CompleteRequest(), but it's wrong.
Second - to do what you describe,
you'll need to insure that the zip file can be created correctly and in its entirety, before sending anything. That means you should do the AddResponseDataForZipFile() only after the zipfile is completely created. That means you need to create an actual zip file on the server, and not simply save out to Response.OutputStream. Once the file is successfully created, then call AddResponseDataForZipFile(), stream the bytes for the temp zip file, call Response.Close(), then delete the temporary zip file.
I can't comment at the moment, so take this answer as one.
How does Utils.ExportToZip work?
If the reason it takes the Response.OutputStream for the constructor is to write the zip-file directly into it, then you need to set Buffering in order to "undo" that in your AddResponseDataForZipFile Method:
Response.BufferOutput = true;

ASP.NET show PDF file to user instead of "save as" dialog

My ASP.NET application return PDF file to user using code below
Context.Response.Clear();
Context.Response.ContentType = "application/pdf";
Context.Response.TransmitFile(optionEntityCmd.PathToSave);
Context.Response.End();
This code show Save As browser dialog, is it possible instead of Save As dialog load PDF file directly in browser?
You could append the Content-Disposition header:
Context.Response.AppendHeader(
"Content-Disposition",
"inline; filename=foo.pdf"
);
Is it a dynamically created file? If not, you can just hyperlink or Response.Redirect to it I believe.
I do not know for sure for classic asp.net but using mvc, streaming it to the user does what you want:
MemoryStream stream = PDF.GeneratePDFByStream();
stream.Flush(); //Always catches me out
stream.Position = 0; //Not sure if this is required
return stream;
with
public static MemoryStream GeneratePDFByStream() {
var doc1 = new Document();
//use a variable to let my code fit across the page...
string path = AppDomain.CurrentDomain.BaseDirectory + "PDFs";
MemoryStream stream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc1, stream);
writer.CloseStream = false;
// Actual Writing
doc1.Open();
// writing comes here, you will probably just load the PDF in a stream?
doc1.Close();
return stream;
}
And your MVC controller returns something like
return File(GetPDFStream(id), "application/pdf");
So, I know this is not the exact answer you are looking for, but maybe you should try to stream your PDF to the user as it will open it in a new tab as far as I ever tested it.
From the top of my head, you should get something like:
Response.Clear();
Response.ContentType = "application/pdf";
Response.OutputStream.Write( objMemoryStream.ToArray(), 0,
Convert.ToInt32(objMemoryStream.Length));
Response.Flush();
try { Response.End(); } catch{}

ASP.NET Return image from .aspx link

Is it possible to output an image (or any file type) to a download link when a user clicks on a link from another ASP.NET page?
I have the file name and byte[].
Get File
...where getfile returns the file instead of going to the getfile.aspx page.
You would want .ashx for that really ;)
public class ImageHandler : IHttpHandler
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext ctx)
{
var myImage = GetImageSomeHow();
ctx.Response.ContentType = "image/png";
ctx.Response.OutputStream.Write(myImage);
}
}
How to Create Text Image on the fly with ASP.NET
Something like this:
string Path = Server.MapPath(Request.ApplicationPath + "\image.jpg");
Bitmap bmp = CreateThumbnail(Path,Size,Size);
Response.ContentType = "image/jpeg";
bmp.Save(Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
Here is how I have done this in the past:
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Disposition", string.Format("inline;filename=\"{0}.pdf\"",Guid.NewGuid()));
Response.ContentType = #"application/pdf";
Response.WriteFile(path);
Yeah, you have to clear the response completely and replace it with the image byte data as a string, and you need to make sure to set the response header for content-type according to the type of image
Yes, this is possible. There are two parts of the Response object you need to set: the Content-Type and the HTTP Header. The MSDN documentation has the details on the response object but the main concept is pretty simple. Just set the code to something like this (for a Word doc).
Response.ContentType="application/ms-word";
Response.AddHeader("content-disposition", "attachment; filename=download.doc");
There is a more complete example here
the codebehind code for getfile.aspx has to have a content-type and the browser will know that it is an image or a unknown file and will let you save it.
In asp.net you can set the ContentType by using the Response object, i.e.
Response.ContentType = "image/GIF"
Here you have a tutorial for dynamically generated image
ashx...
public class ImageHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
string path = ".....jpg";
byte[] imgBytes = File.ReadAllBytes(path);
if (imgBytes.Length > 0)
{
ctx.Response.ContentType = "image/jpeg";
ctx.Response.BinaryWrite(imgBytes);
}
}
public bool IsReusable
{
get {return false;}
}
}

Resources