WCF下载文件被客户端中止

时间:2018-10-14 11:50:06

标签: c# .net wcf download httpcontext

我有以下用于下载大文件的代码。它从文件流读取并写入Response.Outputstream。

它似乎正在工作,即该文件似乎正在下载(奇怪的是,实际上似乎正在下载更多文件),但最终失败。 Chrome给出“网络错误”,IE显示“(已中止)”

    [OperationContract]
    [WebInvoke(UriTemplate = "/f/{key}", Method = "GET")]
    public void LargeFileDownload(string key)
    {
        var identifier = PublicIdentifier.FromString(key, true);
        if (identifier.Type == PublicIdentifier.IdentifierType.DocumentDownload)
        {
            Document doc = Business.Documents.GetById(Application.SystemUser, identifier.Id);

            string tempName = Path.GetTempPath() + doc.OriginalFileName;

            int bufferSize = 8192;
            FileStream fstream = new FileStream(tempName, FileMode.Open, FileAccess.Read);
            long fileSize = fstream.Length;

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ContentType = doc.ContentType;

            string contentDisposition = string.Format("{0};filename={1}{2}", "attachment", doc.Name.Replace(" ", "_"), Path.GetExtension(doc.OriginalFileName));
            HttpContext.Current.Response.AddHeader("Content-Disposition", contentDisposition);
            HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());

            WebOperationContext.Current.OutgoingResponse.ContentType = doc.ContentType;
            try
            {
                byte[] buffer = new byte[bufferSize];

                int bytesRead = 0;
                while ((bytesRead = fstream.Read(buffer, 0, bufferSize)) > 0)
                {
                    HttpContext.Current.Response.OutputStream.Write(buffer, 0, bufferSize);
                    HttpContext.Current.Response.Flush();
                }
            }
            finally
            {
                if (fstream != null)
                    fstream.Close();

                //File.Delete(tempName);
            }
        }
    }

更新的代码:-

    [OperationContract]
    [WebInvoke(UriTemplate = "/f/{key}", Method = "GET")]
    public void LargeFileDownload(string key)
    {
        var identifier = PublicIdentifier.FromString(key, true);
        if (identifier.Type == PublicIdentifier.IdentifierType.DocumentDownload)
        {
            Document doc = Business.Documents.GetById(Application.SystemUser, identifier.Id);

            string tempName = Path.GetTempPath() + doc.OriginalFileName;

            int bufferSize = 8192;
            FileStream fstream = new FileStream(tempName, FileMode.Open, FileAccess.Read);
            long fileSize = fstream.Length;

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ContentType = "application/octet-stream";

            string contentDisposition = string.Format("{0};filename={1}{2}", "attachment", doc.Name.Replace(" ", "_"), Path.GetExtension(doc.OriginalFileName));
            HttpContext.Current.Response.AddHeader("Content-Disposition", contentDisposition);
            HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());

            HttpContext.Current.Response.ContentType = "application/octet-stream";
            try
            {
                byte[] buffer = new byte[bufferSize];

                int bytesRead = 0;
                while ((bytesRead = fstream.Read(buffer, 0, bufferSize)) > 0)
                {
                    HttpContext.Current.Response.OutputStream.Write(buffer, 0, bytesRead);
                    HttpContext.Current.Response.Flush();
                }
            }
            finally
            {
                if (fstream != null)
                    fstream.Close();

                //File.Delete(tempName);
            }
        }
    }

提琴手原始:-

HTTP/1.1 504 Fiddler - Receive Failure
Date: Wed, 17 Oct 2018 11:53:09 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Cache-Control: no-cache, must-revalidate
Timestamp: 12:53:09.099

[Fiddler] ReadResponse() failed: The server did not return a complete response for this request. Server returned 13,912,938 bytes.

1 个答案:

答案 0 :(得分:0)

您正确设置了Content-Length,浏览器假定该值为true。但是由于这个错误,您正在发送更多数据(这是垃圾):

HttpContext.Current.Response.OutputStream.Write(buffer, 0, bufferSize);

这不应该是bufferSize,而应该是bytesRead。这会导致协议错误,导致浏览器中止其处理。

复制循环可能应该由对TransmitFile的调用或至少由Stream.Copy的调用来代替。