C# 在 asp.net/mvc 中控制器内的操作中向 http 响应添加标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16094652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
adding header to http response in an action inside a controller in asp.net/mvc
提问by ezile
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:
我正在将数据从服务器流式传输到客户端以使用filestream.write. 在这种情况下,发生的情况是我能够下载该文件,但它在我的浏览器中没有显示为下载。“另存为”的弹出窗口不会出现在“下载”部分,也不会出现“下载栏”。环顾四周,我想我需要在响应标头中包含“某物”以告诉浏览器此响应有附件。我也想设置cookie。为了实现这一点,这就是我正在做的事情:
[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."
我收到错误消息:“System.web.httpcontext.current 是一个属性,用作类型。”
Am I doing the header updating at the right place? Is there any other way to do this?
我是否在正确的位置进行标题更新?有没有其他方法可以做到这一点?
回答by PSL
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)
UpdateAs 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.
更新据我所知,您正在对您的控制器/操作进行 ajax 调用,该调用无法通过直接调用操作来下载文件。你可以通过这种方式实现它。
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.
在您的 JS 按钮中单击您可以执行类似的操作。
$('#btnDownload').click(function () {
window.location.href = "controller/download?name=yourargument";
});
回答by Abhinav
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:
编辑1:
Adding something that might be more of your interest from our good ol' SO. You can check for complete detail here.
从我们的好 ol' SO 中添加您可能更感兴趣的东西。您可以在此处查看完整的详细信息。
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);
}
回答by Mathijs Flietstra
Change:
改变:
return RedirectToAction("Index");
to:
到:
return File(fs, "your/content-type", "filename");
And move the return statement to inside your using statement.
并将 return 语句移到 using 语句中。
回答by Wayne
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.
过去,我建立了一个白名单,以允许某些域对我的网站进行 iframe。还请记住用于 iframe 站点的 Google 图像缓存。
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);
}
}
回答by akash singla
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;
}

