I am streaming data from server to client for download using filestream.write
. In that case what is happening is that I am able to download the file but it does not appear as download in my browser. Neither the pop-up for "Save As" appears not "Download Bar" appears in Downloads section. From looking around, I guess I need to include "something" in the response header to tell the browser that there is an attachment with this response. Also I want to set the cookie. To accomplish this, this is what I am doing:
[HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name)]
public ActionResult Download(string name)
{
// some more code to get data in inputstream.
using (FileStream fs = System.IO.File.OpenWrite(TargetFile))
{
byte[] buffer = new byte[SegmentSize];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, SegmentSize)) > 0)
{
fs.WriteAsync(buffer, 0, bytesRead);
}
}
}
return RedirectToAction("Index");
}
I am getting error that: "System.web.httpcontext.current is a property and is used as a type."
Am I doing the header updating at the right place? Is there any other way to do this?
Yes, You are doing it the wrong way try this, you should add the header inside your action not as an attribute header to your method.
HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name)
or
Request.RequestContext.HttpContext.Response.AddHeader("Content-Disposition", "Attachment;filename=" & name)
Update
As i understand you are making an ajax call to your controller/action which wont work for file download by directly calling an action. You can achieve it this way.
public void Download(string name)
{
//your logic. Sample code follows. You need to write your stream to the response.
var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf");
var stream = new MemoryStream(filestream);
stream.WriteTo(Response.OutputStream);
Response.AddHeader("Content-Disposition", "Attachment;filename=targetFileName.pdf");
Response.ContentType = "application/pdf";
}
or
public FileStreamResult Download(string name)
{
var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf");
var stream = new MemoryStream(filestream);
return new FileStreamResult(stream, "application/pdf")
{
FileDownloadName = "targetfilename.pdf"
};
}
In your JS button click you can just do something similar to this.
$('#btnDownload').click(function () {
window.location.href = "controller/download?name=yourargument";
});
Please take a look here.
Following is taken from referenced website.
public FileStreamResult StreamFileFromDisk()
{
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
string fileName = "test.txt";
return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
}
Edit 1:
Adding something that might be more of your interest from our good ol' SO.
You can check for complete detail here.
public ActionResult Download()
{
var document = ...
var cd = new System.Net.Mime.ContentDisposition
{
// for example foo.bak
FileName = document.FileName,
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(document.Data, document.ContentType);
}
Change:
return RedirectToAction("Index");
to:
return File(fs, "your/content-type", "filename");
And move the return statement to inside your using statement.
In the past I built a whitelist to allow some domains to iframe my site. Remember Google's image cache used to iframe sites as well.
static HashSet<string> frameWhiteList = new HashSet<string> { "www.domain.com",
"mysub.domain.tld",
"partner.domain.tld" };
protected void EnforceFrameSecurity()
{
var framer = Request.UrlReferrer;
string frameOptionsValue = "SAMEORIGIN";
if (framer != null)
{
if (frameWhiteList.Contains(framer.Host))
{
frameOptionsValue = string.Format("ALLOW-FROM {0}", framer.Host);
}
}
if (string.IsNullOrEmpty(HttpContext.Current.Response.Headers["X-FRAME-OPTIONS"]))
{
HttpContext.Current.Response.AppendHeader("X-FRAME-OPTIONS", frameOptionsValue);
}
}
public FileResult DownloadDocument(string id)
{
if (!string.IsNullOrEmpty(id))
{
try
{
var fileId = Guid.Parse(id);
var myFile = AppModel.MyFiles.SingleOrDefault(x => x.Id == fileId);
if (myFile != null)
{
byte[] fileBytes = myFile.FileData;
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, myFile.FileName);
}
}
catch
{
}
}
return null;
}