简体   繁体   English

从ASP.Net Web API返回文件

[英]Returning a file from ASP.Net Web API

I am trying to return a file from an ASP API method. 我正在尝试从ASP API方法返回文件。

The strange thing is, it works in IE (It has been a long time since I have said that). 奇怪的是,它在IE中有效(自从我这么说以来已经很长时间了)。

In other browsers (Chrome and Firefox) it repeats the call continuously (a breakpoint in the method gets hit multiple times) 在其他浏览器(Chrome和Firefox)中,它会连续重复调用(方法中的断点会被多次击中)

Has anybody ever has anything like this, or does anyone know what might be causing this. 有没有人遇到过这样的事情,或者没有人知道是什么原因造成的。

The code: 编码:

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;
}

I have also tried loading the stream into a byte array, and using a ByteArrayContent . 我还尝试将流加载到字节数组中,并使用ByteArrayContent I have checked the position of stream while in breat mode. 我已经在breat模式下检查了流的位置。 Since id does work in IE I don't think there is anything wrong with the stream. 由于id确实可以在IE中工作,所以我认为流没有任何问题。

Incase one of these is doing something funny and instructing the browser to try again, this is a list of headers returned: 如果其中之一正在做一些有趣的事情并指示浏览器重试,这是返回的标头列表:

Access-Control-Allow-Credentials → true 访问控制允许凭证 →true
Access-Control-Allow-Headers → X-Requested-With, origin, content-type, accept 访问控制允许标题 →X-Requested-With,来源,内容类型,接受
Access-Control-Allow-Methods → GET, PUT, POST, DELETE, HEAD, OPTIONS 访问控制允许方法 →GET,PUT,POST,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin → * 访问控制允许来源 →*
Cache-Control → no-cache 缓存控制 →无缓存
Content-Disposition → Attachment; 内容处置 →附件; filename=Report.xlsx filename = Report.xlsx
Content-Length → 16702 内容长度 →16702
Content-Type → application/vnd.ms-excel 内容类型 →application / vnd.ms-excel
Date → Wed, 07 Feb 2018 06:08:17 GMT 日期 →2018年2月7日星期三06:08:17 GMT
Expires → -1 过期 →-1
Pragma → no-cache 语用 →不缓存
Request-Context → appId=cid-v1:8fcfeca5-8450-44d8-a0de-35724f4e81f3 请求上下文 →appId = cid-v1:8fcfeca5-8450-44d8-a0de-35724f4e81f3
Server → Microsoft-IIS/10.0 服务器 →Microsoft-IIS / 10.0
X-AspNet-Version → 4.0.30319 X-AspNet版本4.0.30319
X-Powered-By → ASP.NET X-Powered-By →ASP.NET
X-SourceFiles → =?UTF-8?B?QzpcVXNlcnNcbWVcU291cmNlXFJlcG9zXE11c2tldGVlclxJR1NcYXBpXEV4Y2VsKDEwMjgyLDAsMCwwKQ==?= X源文件 →=?UTF-8?B?QzpcVXNlcnNcbWVcU291cmNlXFJlcG9zXE11c2tldGVlclxJR1NcYXBpXEV4Y2VsKDEwMjgyLDAsMCwwKQ ===
X-StackifyID → V1|80000015-0002-f500-b63f-84710c7967bb| X-StackifyID →V1 | 80000015-0002-f500-b63f-84710c7967bb |

Any ideas would be appreciated. 任何想法,将不胜感激。

Try using a filestream result 尝试使用文件流结果

public FileStreamResult GetExcel(){
    var memoryStream = new MemoryStream(stream);            
    string filename = "Report.xlsx";
    return new FileStreamResult(memoryStream, "application/vnd.ms-excel") { 
        FileDownloadName = filename };
}

Try, if this helps. 如果有帮助,请尝试。

    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);
        }
    }

You should send the file as an binary file with the media type "application/octet-stream". 您应该以媒体类型“ application / octet-stream”的二进制文件形式发送文件。 This works in most browsers and when the attachment has a filename extension associated with it, the browser will try to resolve how to open the content by itself 这在大多数浏览器中都有效,并且当附件具有关联的文件扩展名时,浏览器将尝试解决如何自行打开内容的问题。

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();
    }
}

You should care about MakeReport method, MemoryStream may help, like this: 您应该关心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;
        }
    }

The method GetExcel looks good. GetExcel方法看起来不错。 (Tested with Chrome: file auto downloaded) (经过Chrome测试:自动下载文件)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM