C# 使用Page.Response向用户发送文件后,Page不会';不回答

C# 使用Page.Response向用户发送文件后,Page不会';不回答,c#,asp.net,postback,response,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.I

我已经创建了一个页面,允许用户在单击按钮时下载文件。。。按钮的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和调用Response.Redirect的两个建议,从按钮的click事件重定向到处理程序

    void submitButton_Click(object sender, EventArgs e)
    {
        label.Text = "Boo!";
        this.Page.Response.Redirect("~/ViewAttachment.ashx?id=foo", false);
    }

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

使用Response.Clear()您已经删除了标题。虽然浏览器中似乎有有效的html标记,但实际上没有。标题已消失,因此看起来仍在渲染的控件无效。如果单击“上一步”,您应该能够重新发布信息。您可能需要在不同的窗口中使用按钮单击中的PostBackUrl进行此调用,并将表单的目标设置为不同的窗口(然后使用SetTimeout将其重置为_self)。

使用Response.Clear()您已经删除了标题。虽然浏览器中似乎有有效的html标记,但实际上没有。标题已消失,因此看起来仍在渲染的控件无效。如果单击“上一步”,您应该能够重新发布信息。您可能希望在不同的窗口中使用按钮单击中的PostBackUrl进行此调用,并将表单的目标设置为不同的窗口(然后使用SetTimeout将其重置为_self)。

如果使用其他处理程序,是否使用选项

这是我以前使用过的精简版本(这是一篇简短的文章)。(AttachmentFile只是一个类,包含上传文件时收集的blob数据和一些属性):

然后,您只需在页面上以
~/ViewAttachment.ashx?ID=5
的形式呈现一个链接,单击该按钮即可下载文件,但不会影响页面的生命周期


现在还有更多的考虑因素,比如安全性等等……我在这个例子中删掉了它们。我也在使用这种链接:
~/Attachment/{id}
通过webforms路由…如果您对其中任何一个感兴趣,我将更新以包含它们。或者你可能会讨厌这种方法……只是让你知道这是一个选项。

如果使用另一个处理程序作为选项

这是我以前使用过的精简版本(这是一篇简短的文章)。(AttachmentFile只是一个类,包含上传文件时收集的blob数据和一些属性):

然后,您只需在页面上以
~/ViewAttachment.ashx?ID=5
的形式呈现一个链接,单击该按钮即可下载文件,但不会影响页面的生命周期

现在还有更多的考虑因素,比如安全性等等……我在这个例子中删掉了它们。我也在使用这种链接:
~/Attachment/{id}
通过webforms路由…如果您对其中任何一个感兴趣,我将更新以包含它们。或者你可能会讨厌这种方法……只是让你知道这是一种选择。

你基本上就是这样

您需要在按钮单击事件处理程序中执行的全部操作是响应。重定向到另一个ASPX页面。把你写的代码放到另一页上

然后一切都会像你期望的那样工作。浏览器实际上会停留在原始页面上,而不会转到新页面,因为您已将内容配置设置为“附件”-这很好。

您大部分时间都在那里

您需要在按钮单击事件处理程序中执行的全部操作是响应。重定向到另一个ASPX页面。把你写的代码放到另一页上


然后一切都会像你期望的那样工作。浏览器实际上会停留在原始页面上,而不会转到新页面,因为您已将内容配置设置为“附件”-这很好。

重定向是否有误?它仍然不起作用。有关详细信息,请参阅编辑…我是否做了错误的重定向?它仍然不起作用。有关详细信息,请参阅编辑…好的,我想我已经实现了您建议的大部分内容,但我仍然得到这种行为,导致它在重定向到另一个页面后没有响应。你还有别的想法吗?@tbischel-不要重定向:)只要把那个按钮设为指向那个url的超链接,你就都准备好了。我一定是疯了。。。我已将按钮的回发url设置到页面。。。同样的问题。我真的要创建一个超链接并在其中放置一个按钮控件吗?@tbischel-执行类似操作:
单击我
…或者给它一个ID并从代码隐藏中设置NavigateUrl。好的,我想我已经基本实现了你的建议,但我仍然会遇到这种行为,导致它在重定向到另一个页面后没有响应。你还有别的想法吗?@tbischel-不要重定向:)只要把那个按钮设为指向那个url的超链接,你就都准备好了。我一定是疯了。。。我已将按钮的回发url设置到页面。。。同样的问题。我真的要创建一个超链接并在其中放置一个按钮控件吗?@tbischel-执行类似操作:
单击我
…或者给它一个ID并从代码后面设置NavigateUrl。
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;
  }
}
<system.web>
  <httpHandlers>
    <add verb="*" path="ViewAttachment.ashx" type="MyNamespace.AttachmentHandler, MyWebDllName"/>
  </httpHandlers>
</system.web>