在.NET中缓存时无法获得稳定的304响应

时间:2013-11-19 18:37:47

标签: c# caching

我需要在文件级别控制缓存。

有时我可以在重新加载文件时得到304响应 - 但大多数情况下都没有。 我的缓存设置在这里做错了什么?

    public static void GetAndOutputFile(string url, int maxAgeInHours, string key)
    {
        Stream stream = null;
        const int bytesToRead = 100000;

        byte[] buffer = new Byte[bytesToRead];

        try
        {
            HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);

            HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();

            if (fileReq.ContentLength > 0)
                fileResp.ContentLength = fileReq.ContentLength;

            stream = fileResp.GetResponseStream();

            var resp = HttpContext.Current.Response;
            resp.ContentType = fileResp.ContentType; 

            //Set cache
            resp.Cache.SetCacheability(HttpCacheability.Public);
            resp.Cache.SetSlidingExpiration(false);

            resp.Cache.SetLastModified(DateTime.Parse("1/1/2001 00:00:01AM"));
            resp.Cache.SetMaxAge(TimeSpan.FromHours(maxAgeInHours));
            resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));

            MemoryStream ms = new MemoryStream();
            int length;
            do
            {
                if (resp.IsClientConnected)
                {
                    length = stream.Read(buffer, 0, bytesToRead);

                    resp.OutputStream.Write(buffer, 0, length);
                    ms.Write(buffer, 0, length);

                    resp.Flush();

                    buffer = new Byte[bytesToRead];
                }
                else
                {
                    length = -1;
                }
            } while (length > 0); //Repeat until no data is read

        }

        finally
        {
            if (stream != null)
            {
                //Close the input stream
                stream.Close();
                stream.Dispose();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

找到解决方案。关键问题是必须在.NET中自己设置304。

public static void GetAndOutputFile(string url,int maxAgeInHours,string key) {

if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["If-Modified-Since"]))
{
    CultureInfo provider = CultureInfo.InvariantCulture;
    var lastMod = DateTime.ParseExact(HttpContext.Current.Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
    if (lastMod < DateTime.UtcNow.ToLocalTime())
    {
        HttpContext.Current.Response.StatusCode = 304;
        HttpContext.Current.Response.StatusDescription = "Not Modified";
        return;
    }
}
Stream stream = null;
const int bytesToRead = 100000;

byte[] buffer = new Byte[bytesToRead];
try
{
    HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(url);
    HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();

    if (fileReq.ContentLength > 0)
        fileResp.ContentLength = fileReq.ContentLength;
    stream = fileResp.GetResponseStream();
    var resp = HttpContext.Current.Response;

    resp.ContentType = fileResp.ContentType;
    resp.Cache.SetCacheability(HttpCacheability.Public);
    resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));
    resp.Cache.SetLastModified(DateTime.UtcNow.AddMinutes(-1));

    MemoryStream ms = new MemoryStream();
    int length;
    do
    {
        if (resp.IsClientConnected)
        {
            length = stream.Read(buffer, 0, bytesToRead);
            resp.OutputStream.Write(buffer, 0, length);
            ms.Write(buffer, 0, length);
            resp.Flush();
            buffer = new Byte[bytesToRead];
        }
        else
        {
            length = -1;
        }
    } while (length > 0); //Repeat until no data is read

}
finally
{
    if (stream != null)
    {
        //Close the input stream
        stream.Close();
        stream.Dispose();
    }
}