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

发布于 2024-08-20 05:23:00 字数 901 浏览 4 评论 0原文

我创建了一个页面,允许用户在单击按钮时下载文件...按钮的 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 到处理程序。

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

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

I've created a page that allows users to download a file when they click a button... the button's onclick event is linked to the following chunk of code:

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();

The download works fine, but now when I try to interact with the page, (for instance, hit the download button again), nothing posts back.

Am I responding to the download request incorrectly (should I be using a different/new response object), or is there something else I need to do to make the page active after the download?


Edit:

So I've tried encorporating the two posters suggestions for creating a httphandler, and calling a Response.Redirect to the handler from the button's click event.

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

If I step through this on the debugger, it continues after the redirect call, but the page just returns to a state where the button doesn't work, and the labels have their default values. Am I now doing the redirect wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

懒猫 2024-08-27 05:23:00

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

这是我之前使用过的精简版(欢迎提出建议,这是一篇快速编写的文章)。 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}...如果您对其中任何一个感兴趣,我将更新以包含它们。或者您可能完全讨厌这种方法......只是让您知道这是一种选择。

If using another handler an option?

Here's a slimmed down version of what I've used before (suggestions welcome this was a quick write). The HttpHandler (AttachmentFile is just a class with the blob data and some attributes collected when the file was uploaded):

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;
  }
}

In the web.config:

<system.web>
  <httpHandlers>
    <add verb="*" path="ViewAttachment.ashx" type="MyNamespace.AttachmentHandler, MyWebDllName"/>
  </httpHandlers>
</system.web>

Then all you do is render a link in the form of ~/ViewAttachment.ashx?ID=5 on the page, clicking the button will download the file, but not mess with your page's lifecycle at all.

Now there are more considerations, like security and such....I trimmed them out for this example. I'm also using this style of link: ~/Attachment/{id} via webforms routing...if either of these interest you I'll update to include them. Or you could hate this approach all-together...just letting you know it's an option.

花间憩 2024-08-27 05:23:00

你大部分时间都在那里。

您在按钮单击事件处理程序中所需要做的就是 Response.Redirect 到另一个 ASPX 页面。将您编写的代码放在另一页上。

然后一切都会按照你的预期进行。浏览器实际上会停留在原始页面上,不会转到新页面,因为您已将内容配置设置为附件 - 这很棒。

You are mostly there.

All you need to do in your button click event handler is Response.Redirect to another ASPX page. Put that code your wrote on the other page.

Then everything will work just as you expect. The browser will actually stay on the original page and not go to the new page because you have set the content disposition to attachment - which is great.

爱格式化 2024-08-27 05:23:00

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

By using Response.Clear() you've killed the headers. While there may appear to be valid html markup in the browser there really isn't. The headers are gone, so the controls that appear to be still rendered aren't valid. If you click "back" you should be able to repost information. What you probably want to do is make this call in a different window using PostBackUrl in your button click and setting the target of your form to a different window (then using SetTimeout to reset it to _self).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文