为什么在使用Server.Transfer()时不会创建HTTP头?

时间:2012-10-25 13:28:00

标签: asp.net caching http-headers webserver server.transfer

我正在使用.aspx页面根据给定的参数从文件系统提供图像文件。

Server.Transfer(imageFilePath);

此代码运行时,会提供映像,但不会创建 Last-Modified HTTP标头。 与同一文件相对,直接从同一服务器上的URL调用。

因此浏览器不会发出 If-Modified-Since 并且不会缓存响应。

有没有办法让服务器创建HTTP标头,就像通常直接请求文件一样(在这种情况下是图像),还是我必须手动创建标题?

2 个答案:

答案 0 :(得分:1)

当您转移到文件时,服务器将返回与.aspx文件相同的标头,因为它基本上由.NET引擎执行。

您基本上有两个选择:

  • 改为重定向到文件,以便浏览器发出请求。

  • 设置所需的标题,并使用Request.BinaryWrite(或更熟悉的)在回复中发回文件数据。

答案 1 :(得分:1)

我将扩展@Guffa的答案并分享我选择的解决方案。

调用Server.Transfer方法时,.NET引擎会将其视为.aspx页面,因此在提供静态文件时,它不会添加所需的相应HTTP标头(例如用于缓存)。

有三个选项

  • 使用Response.Redirect,以便浏览器发出相应的请求
  • 设置所需的标头并使用Request.BinaryWrite提供内容
  • 设置所需的标头并致电Server.Transfer

我选择第三个选项,这是我的代码:

        try
        {
            DateTime fileLastModified = File.GetLastWriteTimeUtc(MapPath(fileVirtualPath));
            fileLastModified = new DateTime(fileLastModified.Year, fileLastModified.Month, fileLastModified.Day, fileLastModified.Hour, fileLastModified.Minute, fileLastModified.Second);
            if (Request.Headers["If-Modified-Since"] != null)
            {
                DateTime modifiedSince = DateTime.Parse(Request.Headers["If-Modified-Since"]);

                if (modifiedSince.ToUniversalTime() >= fileLastModified)
                {
                    Response.StatusCode = 304;
                    Response.StatusDescription = "Not Modified";
                    return;
                }
            }
            Response.AddHeader("Last-Modified", fileLastModified.ToString("R"));
        }
        catch
        {
            Response.StatusCode = 404;
            Response.StatusDescription = "Not found";
            return;
        }
        Server.Transfer(fileVirtualPath);