我有一个WCF服务,它提供一个动态生成QR码图像的端点。首先将图像写入内存流tempStream
。然后我在端点中有以下代码:
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = false;
response.ContentType = "image/png";
response.CacheControl = "No-Cache";
response.AddHeader("Content-Length", tempStream.Length.ToString())
response.AddHeader("Accept-Ranges", "bytes");
tempStream.WriteTo(response.OutputStream);
response.Flush();
response.End();
它在Firefox中运行良好。如果我手动点击端点,则会下载图像,如果我将端点作为src
标记中的img
属性引用,则会加载内联。但是,在IE中,图像不会在img
标记中内嵌加载,如果我尝试手动命中端点,它会在第一次加载完整图像但后续刷新(看起来直到浏览器重新启动) ,它只加载部分图像。
在检查F12窗口中的网络选项卡时,它似乎正在从服务器下载1.00 KB的数据(包括标题),这意味着它可以获得大约750 KB的图像数据。然后它向服务器发出另一个相同的请求,只返回没有图像数据的标题。 Content-Length
标题已正确设置为图像的大小; IE只是没下载那么多。再一次,Firefox很好。
我的同事建议我将transferMode
设置为Streamed
Web.config
,我做了,但这也不起作用。如何让IE一次下载整个图像?
修改
我应该注意,在Visual Studio的IIS Express服务器中运行WCF服务时,Internet Explorer运行正常。只有在将应用程序部署到IIS 7.5时才会出现问题。 Firefox在这两种环境中都可以正常工作。
编辑2:
我刚刚在Thread.Sleep(1000)
之前向响应添加了response.End()
,并解决了问题。 IE现在下载整个响应,不会尝试发出第二个请求。为什么?! response.Flush();
应该阻止请求并在调用response.End()
之前向客户端发送所有数据,据我所知,response.End()
也会刷新流以便调用Flush()
手动是多余的。为什么明确地阻塞线程一秒使它工作?我还应该注意,如果我没有放入Thread.Sleep(1000)
,它仍适用于第一个请求,因为每次重新启动AppPool时,.NET都必须对后端进行JIT编译,阻止请求一段时间,就像Thread.Sleep(1000)
那样。
答案 0 :(得分:0)
试试这个:
response.AddHeader("Content-Disposition", "filename=" + fileName);
答案 1 :(得分:0)
好的,我现在真的解决了。我没有使用HttpContext.Current.Response,而是使用WebOperationContext.Current.OutgoingResponse。另外,我没有写入响应的输出流,而是从端点返回一个Stream对象,特别是MemoryStream我将图像保存到(在它被搜索回0之后) 。在传输完成之前,似乎没有一种一致的方法可以对HttpResponse
块进行写操作,因此请求总是很快结束。甚至Firefox也存在较大图像的问题。从端点函数返回Stream
对象显然会使WCF等待,直到所有数据都被发送为止。