[英]Returning a file from ASP.Net Web API
我正在尝试从ASP API方法返回文件。
奇怪的是,它在IE中有效(自从我这么说以来已经很长时间了)。
在其他浏览器(Chrome和Firefox)中,它会连续重复调用(方法中的断点会被多次击中)
有没有人遇到过这样的事情,或者没有人知道是什么原因造成的。
编码:
public async Task<HttpResponseMessage> GetExcel()
{
var stream = await MakeReport();
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentLength = stream.Length;
result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddDays(-1));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Attachment") { FileName = "Report.xlsx" };
return result;
}
我还尝试将流加载到字节数组中,并使用ByteArrayContent
。 我已经在breat模式下检查了流的位置。 由于id确实可以在IE中工作,所以我认为流没有任何问题。
如果其中之一正在做一些有趣的事情并指示浏览器重试,这是返回的标头列表:
访问控制允许凭证 →true
访问控制允许标题 →X-Requested-With,来源,内容类型,接受
访问控制允许方法 →GET,PUT,POST,DELETE,HEAD,OPTIONS
访问控制允许来源 →*
缓存控制 →无缓存
内容处置 →附件; filename = Report.xlsx
内容长度 →16702
内容类型 →application / vnd.ms-excel
日期 →2018年2月7日星期三06:08:17 GMT
过期 →-1
语用 →不缓存
请求上下文 →appId = cid-v1:8fcfeca5-8450-44d8-a0de-35724f4e81f3
服务器 →Microsoft-IIS / 10.0
X-AspNet版本 → 4.0.30319
X-Powered-By →ASP.NET
X源文件 →=?UTF-8?B?QzpcVXNlcnNcbWVcU291cmNlXFJlcG9zXE11c2tldGVlclxJR1NcYXBpXEV4Y2VsKDEwMjgyLDAsMCwwKQ ===
X-StackifyID →V1 | 80000015-0002-f500-b63f-84710c7967bb |
任何想法,将不胜感激。
尝试使用文件流结果
public FileStreamResult GetExcel(){
var memoryStream = new MemoryStream(stream);
string filename = "Report.xlsx";
return new FileStreamResult(memoryStream, "application/vnd.ms-excel") {
FileDownloadName = filename };
}
如果有帮助,请尝试。
public async Task<HttpResponseMessage> GetExcel()
{
var stream = await MakeReport();
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentLength = stream.Length;
result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddDays(-1));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Attachment") { FileName = "Report.xlsx" };
WriteFileToResponse(stream, result);
return result;
}
protected override void WriteFileToResponse(Stream _stream, Response _response)
{
Stream _responseStream = _response.OutputStream;
byte[] buffer = new byte[4096];
while (true)
{
int num = this._stream.Read(buffer, 0, 4096);
if (num == 0)
{
break;
}
_responseStream.Write(buffer, 0, num);
}
}
您应该以媒体类型“ application / octet-stream”的二进制文件形式发送文件。 这在大多数浏览器中都有效,并且当附件具有关联的文件扩展名时,浏览器将尝试解决如何自行打开内容的问题。
protected async Task<HttpResponseMessage> GetExcel()
{
var stream = await MakeReport();
var byteArray = ToByteArray(stream);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(byteArray);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); //attachment will force download
result.Content.Headers.ContentDisposition.FileName = "Report.xlsx";
return result;
}
public static byte[] ToByteArray(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
您应该关心MakeReport
方法, MemoryStream
可能会有所帮助,如下所示:
private async Task<Stream> MakeReport()
{
using (var file = new FileStream(@"[file path]", FileMode.Open))
{
var stream = new MemoryStream();
await file.CopyToAsync(stream);
return stream;
}
}
GetExcel
方法看起来不错。 (经过Chrome测试:自动下载文件)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.