使用Page.Response向用户发送文件后,页面不响应

时间:2010-02-02 23:44:18

标签: c# asp.net postback response

我创建了一个页面,允许用户在单击按钮时下载文件...按钮的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);
    }

如果我在调试器上逐步执行此操作,它将在重定向调用之后继续,但页面只返回到按钮不起作用的状态,并且标签具有其默认值。我现在正在重定向错误吗?

3 个答案:

答案 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)。