我有一个应该传输文件的页面
所有代码都包含在try / catch异常块
中我使用Response.TransmitFile来实际写入文件,当它失败时(由于我的情况下的权限问题),对客户端的响应是一些自动生成的html,其中详细说明了错误,其中一部分说:“未处理在执行当前Web请求期间生成了异常。“
为什么说未处理的异常?
我发现了错误,因为标题已更改为text / html而不是八位字节流,如果文件成功完成,它将被设置为。但似乎对TransmitFile的调用将自己的内容写入Response然后将其刷新,这实际上是不可取的!
我该怎么办?
try
{
String targetFile = Request.Form["filePath"];
if (targetFile == null) throw new Exception("No filename provided");
FileInfo file = new FileInfo(targetFile);
if (!file.Exists)
{
// file not found error
throw new Exception("File not found");
}
Response.ContentType = "APPLICATION/OCTET-STREAM";
Response.AppendHeader("Content-Disposition", "Attachment; Filename=\"" + Path.GetFileName(targetFile) + "\"");
Response.TransmitFile(file.FullName);
}
catch (Exception e)
{
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/html";
StringBuilder sb = new StringBuilder();
// I write my own response in sb - I never see this content sent back!!
Response.Write(sb.ToString());
Response.Flush();
}
答案 0 :(得分:1)
这是我为了让它再次运作所做的。看起来好像这样的黑客......唉!
using (FileStream stream = file.OpenRead())
{
byte[] buffer = new byte[1];
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
throw new Exception("Access denied");
}
Response.ContentType = "APPLICATION/OCTET-STREAM";
Response.AppendHeader("Content-Disposition", "Attachment; Filename=\"" + Path.GetFileName(targetFile) + "\"");
Response.TransmitFile(file.FullName);
}
它现在可以工作,因为我打算...如果它没有读取任何字节我认为它是一个访问被拒绝的错误并转到我的catch块并写下我想要的,而不是一些预先生成的IIS html哪个废墟过程...
(我需要使用jQuery postMessage响应进行响应,因为这是一个AJAX请求)
答案 1 :(得分:1)
Response.TransmitFile将文件直接写入Response流而不缓冲它。
由于它已被写入并发送给客户端,因此您无法在catch块中取回/清除标题等 - 某些响应已经发送给客户端!
作为替代方法,您可以使用Response.WriteFile将文件缓冲到内存(前提是您的Response.Buffer属性或Response.BufferOutput设置为true)。这应该允许你在异常的情况下“收回”。
请记住,这可能会对非常大的文件产生性能影响,因此请为您的方案选择最佳方法。
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.buffer.aspx
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.writefile.aspx