ASP.NET OutputCache和Cookies
|
有谁知道为什么如果我的页面上有cookie,输出缓存不起作用! 示例页面 <%@ Page Language="VB" AutoEventWireup="false" CodeFile="ct.aspx.vb" Inherits="ct" %>
<%@ OutputCache Duration="600" Location="Server" VaryByParam="none" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Cache test</h1>
<p id="rndout" runat="server"></p>
</div>
</form>
</body>
</html>
后面的示例代码: Partial Class ct
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object,e As System.EventArgs) Handles Me.Load
Dim rc As New Random()
Dim rn As Integer
rn = rc.Next()
rndout.InnerHtml = rn.ToString
Response.Cookies("sym")("hello") = "world"
Response.Cookies("sym").Expires = DateTime.Now.AddDays(370)
Response.Cookies("sym").Domain = Application.Get("cookieurl")
End Sub
End Class
当部署到iis 6或7时,这不会缓存,但是如果我注释掉它的3个Response.Cookies行. 在VS中运行时,它可以正常工作. 在我设置response.cookies时,iis / web.config等中是否有一些设置允许outputcache.我理解cookie内容将被缓存,它只是缓存的http响应的一部分. 解决方法在对这个问题进行了一些研究之后,我逐渐理解并解决了这个问题.输出缓存与cookie不兼容的原因 因此,输出缓存不会使用cookie缓存响应的原因是cookie可能是特定于用户的(例如,身份验证,分析跟踪等).如果一个或多个具有属性HttpCookie.Shareable = false的cookie,则输出缓存会认为响应不可缓存. 包含带缓存响应的cookie 这是它变得棘手的地方.输出缓存将响应头和内容缓存在一起,并且在将它们发送回用户之前不提供任何钩子来修改它们. using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Web;
using System.Web.Caching;
using Fasterflect;
namespace CustomOutputCache
{
/// <summary>
/// An output cache provider that has ability to modify the http header collection before a cached response is served back to the user.
/// </summary>
public class HeaderModOutputCacheProvider : OutputCacheProvider
{
private static readonly Type OutputCacheEntryType,HttpCachePolicySettingsType;
private static readonly Type[] ParameterTypes;
public static event EventHandler<CachedRequestEventArgs> RequestServedFromCache;
static HeaderModOutputCacheProvider()
{
var systemWeb = typeof(HttpContext).Assembly;
OutputCacheEntryType = systemWeb.GetType("System.Web.Caching.OutputCacheEntry");
HttpCachePolicySettingsType = systemWeb.GetType("System.Web.HttpCachePolicySettings");
ParameterTypes = new[]{
typeof(Guid),HttpCachePolicySettingsType,typeof(string),typeof(string[]),typeof(int),typeof(List<HeaderElement>),typeof(List<ResponseElement>)
};
}
private readonly ObjectCache _objectCache;
public HeaderModOutputCacheProvider()
{
_objectCache = new MemoryCache("output-cache");
}
#region OutputCacheProvider implementation
public override object Get(string key)
{
var cachedValue = _objectCache.Get(key);
if (cachedValue == null)
return null;
if (cachedValue.GetType() != OutputCacheEntryType)
return cachedValue;
var cloned = CloneOutputCacheEntry(cachedValue);
if (RequestServedFromCache != null)
{
var args = new CachedRequestEventArgs(cloned.HeaderElements);
RequestServedFromCache(this,args);
}
return cloned;
}
public override object Add(string key,object entry,DateTime utcExpiry)
{
_objectCache.Set(key,entry,new CacheItemPolicy { AbsoluteExpiration = utcExpiry });
return entry;
}
public override void Set(string key,new CacheItemPolicy { AbsoluteExpiration = utcExpiry });
}
public override void Remove(string key)
{
_objectCache.Remove(key);
}
#endregion
private IOutputCacheEntry CloneOutputCacheEntry(object toClone)
{
var parameterValues = new[]
{
toClone.GetFieldValue("_cachedVaryId",Flags.InstancePrivate),toClone.GetFieldValue("_settings",toClone.GetFieldValue("_kernelCacheUrl",toClone.GetFieldValue("_dependenciesKey",toClone.GetFieldValue("_dependencies",toClone.GetFieldValue("_statusCode",toClone.GetFieldValue("_statusDescription",CloneHeaders((List<HeaderElement>)toClone.GetFieldValue("_headerElements",Flags.InstancePrivate)),toClone.GetFieldValue("_responseElements",Flags.InstancePrivate)
};
return (IOutputCacheEntry)OutputCacheEntryType.CreateInstance(
parameterTypes: ParameterTypes,parameters: parameterValues
);
}
private List<HeaderElement> CloneHeaders(List<HeaderElement> toClone)
{
return new List<HeaderElement>(toClone);
}
}
public class CachedRequestEventArgs : EventArgs
{
public CachedRequestEventArgs(List<HeaderElement> headers)
{
Headers = headers;
}
public List<HeaderElement> Headers { get; private set; }
public void AddCookies(HttpCookieCollection cookies)
{
foreach (var cookie in cookies.AllKeys.Select(c => cookies[c]))
{
//more reflection unpleasantness :(
var header = cookie.CallMethod("GetSetCookieHeader",Flags.InstanceAnyVisibility,HttpContext.Current);
Headers.Add(new HeaderElement((string)header.GetPropertyValue("Name"),(string)header.GetPropertyValue("Value")));
}
}
}
}
你会像这样连线: <system.web>
<caching>
<outputCache defaultProvider="HeaderModOutputCacheProvider">
<providers>
<add name="HeaderModOutputCacheProvider" type="CustomOutputCache.HeaderModOutputCacheProvider"/>
</providers>
</outputCache>
</caching>
</system.web>
并且可以像这样使用它来插入cookie: HeaderModOutputCacheProvider.RequestServedFromCache += RequestServedFromCache;
HeaderModOutputCacheProvider.RequestServedFromCache += (sender,e) =>
{
e.AddCookies(new HttpCookieCollection
{
new HttpCookie("key","value")
});
}; (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 双引号之间的Razor代码
- asp.net – ActiveDirectoryMembershipProvider – “无法建
- ASP.NET中的应用程序生存期
- asp.net-mvc-3 – 使用接口作为部分视图数据注释的模型类型
- asp.net-mvc-3 – 在ASP.NET MVC中本地化/翻译路由
- asp.net-mvc – ASP.NET MVC运行IIS7部署问题
- 为什么我的IIS7应用程序池在从ASP.NET页面调用的DLL中发生异
- 如何强制我的ASP.net 2.0应用程序重新编译
- asp.net 4.0:是否有相当于ClientIDMode的INPUT的名称?
- 有没有办法我仍然可以在我的ASP.NET MVC 2项目中使用app_of
