【问题标题】:Only count a download once it's served仅在下载后才计算一次下载
【发布时间】:2011-11-23 22:49:33
【问题描述】:

我们有此代码可供下载:

public class downloadRelease : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        -- snip --

        context.Response.Clear();
        context.Response.ContentType = "application/octet-stream";
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + OriginalFileName);
        context.Response.WriteFile(Settings.ReleaseFileLocation + ActualFileName);

        // Log download
        Constructor.VersionReleaseDownload.NewReleaseDownload(ActualFileName);

它工作正常,只是日志下载代码似乎在下载开始时立即运行,而不是在下载完全完成时运行。

有人可以解释这是为什么,以及如何更改它以使其仅在完成时记录?我们不想计算部分下载量。

【问题讨论】:

    标签: c# asp.net download ashx


    【解决方案1】:

    blog post 与您的问题完全相同,也有解决方案。

    Response.Buffer = false;
    Response.TransmitFile("Tree.jpg");
    Response.Close();
    // logging here
    

    【讨论】:

    • 非常感谢!效果很好。虽然它不会发送文件大小,所以下载的时间未知,但我想我可以解决这个问题。
    • context.Response.AddHeader("Content-Length", FileSize.ToString()); 感谢您的代码很有魅力!
    • @TomGullen 我没有得到赏金。
    • 别担心,我正在尝试,但它说我必须等待它为时过早
    【解决方案2】:

    写响应是一个异步过程。它由应用程序的容器管理。在您的情况下,.NET/ASP.net 运行时正在处理它。如果你想知道最后一个块是什么时候发送的,你必须在那个[来自容器/运行时]上有某种回调/事件。在 Java 中,它是获取此信息的应用程序服务器 [Glassfish、Tomcat 等]

    【讨论】:

      【解决方案3】:

      您可以尝试在写入文件之前添加此内容:

      context.Response.BufferOutput = false;
      

      【讨论】:

        【解决方案4】:

        您是否尝试过处理 HttpApplication 的 EndRequest 事件?

        或者,使用 IHttpHandlerFactory 的 ReleaseHandler() 方法,假设您将 IHttpHandler 标记为不可重用?

        【讨论】:

          【解决方案5】:

          这有点棘手...取决于您希望日志记录的精确程度,甚至可能是不可能的...但是Response 对象有以下选项:

          • BinaryWrite / Flush / Close

          • TransmitFile / Flush / Close

          第一个选项要求您在每个块调用BinaryWriteFlush 之后读取文件块......

          第二个选项更容易实现,因为它只是调用TransmitFile,然后调用Flush

          所有内容发送完毕后,登录前您需要致电Close

          在任何情况下,在开始发送响应之前致电DisableKernelCache 会有所帮助...

          注意以上所有内容都会显示出明显的性能影响! 可以通过为您要提供的文件创建内存缓存来减少这种影响...

          至于日志记录,我会考虑将日志记录代码移至EndRequest 事件处理程序...

          AFAIK 这是您最接近目标的方法,除了编写您自己的基于 TcpListener 的 HTTP 服务器或破解 IIS / HTTP.SYS。

          一些参考链接:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-03
            • 2020-06-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多