我创建了一个页面,允许用户在单击按钮时下载文件...按钮的onclick事件链接到以下代码块:
this.Page.Response.Clear();
this.Page.Response.ContentType = System.Net.Mime.MediaTypeNames.Application.Zip;
this.Page.Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + System.IO.Path.GetFileName(filename) + "\"");
this.Page.Response.TransmitFile(filename);
this.Page.Response.Flush();
this.Page.Response.End();
下载工作正常,但现在当我尝试与页面进行交互时(例如,再次点击下载按钮),没有任何回复。
我是否错误地回复了下载请求(我应该使用其他/新的响应对象),还是在下载后我需要做些什么才能使页面处于活动状态?
编辑:
所以我尝试用两个海报建议来创建一个httphandler,并从按钮的click事件中调用Response.Redirect到处理程序。
void submitButton_Click(object sender, EventArgs e)
{
label.Text = "Boo!";
this.Page.Response.Redirect("~/ViewAttachment.ashx?id=foo", false);
}
如果我在调试器上逐步执行此操作,它将在重定向调用之后继续,但页面只返回到按钮不起作用的状态,并且标签具有其默认值。我现在正在重定向错误吗?
答案 0 :(得分:3)
如果使用另一个处理程序?
这是我之前使用的精简版本(建议欢迎这是一个快速写入)。 The HttpHandler(AttachmentFile只是一个包含blob数据的类,以及上传文件时收集的一些属性):
public class AttachmentHandler : IHttpHandler
{
public const string QueryKeyID = "ID";
public void ProcessRequest(HttpContext context)
{
var r = context.Response;
var attachmentID = context.Request.QueryString[QueryKeyID];
Attachment a = DataContext.GetById<AttachmentFile>(attachmentID);
r.ContentType = a.ContentType;
r.AppendHeader("Content-Type", a.ContentType);
r.AppendHeader("content-disposition", string.Format("attachment; filename=\"{0}{1}\"", a.AttachmentName, GetExtension(a.FileName)));
r.BufferOutput = false; //Stream the content to the client, no need to cache entire streams in memory...
r.BinaryWrite(a.BlobData);
r.End();
}
private static string GetExtension(string fileName)
{
if(fileName.IsNullOrEmpty()) return string.Empty;
var i = fileName.LastIndexOf(".");
return i > 0 ? fileName.Substring(i) : string.Empty;
}
}
在web.config
:
<system.web>
<httpHandlers>
<add verb="*" path="ViewAttachment.ashx" type="MyNamespace.AttachmentHandler, MyWebDllName"/>
</httpHandlers>
</system.web>
然后你要做的就是在页面上以~/ViewAttachment.ashx?ID=5
的形式呈现一个链接,单击按钮将下载文件,但不会弄乱页面的生命周期。
现在有更多的考虑因素,比如安全性......我为这个例子修剪了它们。我也使用这种风格的链接:~/Attachment/{id}
通过webforms路由...如果你对这些感兴趣,我会更新以包含它们。或者你可能会讨厌这种方法......只是让你知道这是一个选择。
答案 1 :(得分:1)
你大部分都在那里。
您需要在按钮单击事件处理程序中执行的操作是Response.Redirect到另一个ASPX页面。把你写的代码放在另一页上。
然后一切都会按照您的预期运作。浏览器实际上会保留在原始页面上,而不是转到新页面,因为您已将内容处置设置为附件 - 这很棒。
答案 2 :(得分:0)
通过使用Response.Clear(),您已经杀死了标头。虽然浏览器中可能看起来有效的html标记,但事实并非如此。标题已消失,因此看似仍呈现的控件无效。如果单击“返回”,您应该能够重新发布信息。您可能想要做的是在按钮单击中使用PostBackUrl在不同的窗口中进行此调用,并将窗体的目标设置为不同的窗口(然后使用SetTimeout将其重置为_self)。