在我维护的网站上,https://conservationx.com/
1)Global.asax Session_Start
,只需检查特定名称(visitor
)的cookie,如果不存在,我们将发布一个。
protected void Session_Start()
{
var req = HttpContext.Current.Request;
var cookie = request.Cookies["visitor"];
if (cookie == null)
{
var cookie = new HttpCookie("visitor", sguid);
cookie.Shareable = false; // Do not store in outputcache
cookie.Expires = DateTime.UtcNow.AddYears(1);
response.SetCookie(cookie);
2)在本地Debug中,我可以访问第一个请求,并进入该程序-隐身窗口始终在第一个请求上为我设置Set-Cookie标头。
3)一旦部署,我将永远不会看到在第一次请求时发出Cookie。我始终在第二个请求上看到它。
4)除了看到Set-Cookie标头直到在DevTools的“网络”选项卡中的第二个请求才出现之外,我还添加了日志记录到Session_Start主体,并将其全部包装在try / catch中,记录了所有异常。这同样始终未能在首次访问时触发。这个特定的网站会在页面加载完成后检查您是否已登录,并调用/ account / navaccountinfo-新鲜的浏览器/隐身窗口将始终无法使Cookie集登陆该网站的任何页面,然后查看cookie最终在该次要负载上设置,并且确保我们的日志中充满了在该次要请求URL的请求上设置的cookie。
这是将ASP.Net MVC部署到IIS 7.5的已知问题吗?如果正在使用OWIN和Identity Framework会产生什么影响?
推测,我想知道这是否相关:
OutputCache VaryByCustom cookie value
我设置cookie.Shareable = false
是因为访问者ID在每个浏览器中都是唯一的。无法通过服务器的OutputCache
将其分发给多个人。已访问的初始页面(如/或/ about)已设置OutputCacheAttribute
,并通过GET访问。后续的/ account / navaccountinfo是通过POST访问的,因此,显然从未缓存过。因此,我想知道这是否实际上是OutputCache
和cookie.Shareable = false
之间的不良互动。
答案 0 :(得分:0)
这不是一个好的答案,但这是一个答案,我对其他更优雅的解决方案非常感兴趣。
我们没有在Dev中缓存太多或根本没有缓存,而是在服务器上缓存,因此Session直到Post
被触发后才触发-用户看到了来自IIS的快速缓存响应,这意味着大多数Asp.Net管道永远不会启动,尤其是Session_Start
。帖子总是在缓存中崩溃,瞧,第二次调用-始终是帖子-总是看到cookie集,并且总是看到Session的日志条目。
此外,事实证明,默认情况下,设置HttpCookie.Shareable = false
本质上会在您的缓存中抛出一个炸弹,而且在Dev中不使用太多缓存,我们并没有真正看到此标志造成的重大损害
我们已经在大量使用OutputCache VaryByCustom
了,在这里我们做了一些创造性的工作,例如为公众提供该网站的一个版本,并分别拥有自己的登录成员。有关其工作原理的详细信息超出了此问题的范围,但是足以说明我们在VaryByCustom
中使用Global.asax
:
public override string GetVaryByCustomString(HttpContext context, string key)
{
return VaryByCustomKeyHandler.HandleCacheKey(key, context, Application);
}
键只是我们的编译安全方式,用于指示我们希望对Controller Action进行哪种类型的变化,而我将跳过其详细信息,但是HandleCacheKey
方法现在看起来像这样:< / p>
string uidInSetVisitorCookie = context.Request.ServerVariables["SetVisitorCookie"];
if (uidInSetVisitorCookie != null)
return uidInSetVisitorCookie; // Force vary
因此,如果该用户应该收到Cookie,则基本上我们告诉OutputCache该用户和该用户现在应该自己获得该页面的副本。为此,我们提供了一个恰好是其随机生成的Uid的缓存键。 Uid是在BeginRequest中生成的,我已经证实,即使OutputCache最终将要处理Response的情况下,它也会触发:
protected void Application_BeginRequest(object sender, EventArgs ev)
{
var req = (Brass9.Web.Visiting.Req)HttpContext.Current.Request;
string uid = AnonCookieManager.O.GetUid(req);
bool hadNoCookie = String.IsNullOrEmpty(uid);
if (hadNoCookie)
{
uid = (Brass9.ShortGuid.NewGuid()).ToString();
AnonCookieManager.O.PutCookie(HttpContext.Current.Response, uid);
req.ServerVariables["SetVisitorCookie"] = uid;
}
因此,其中有许多灯光库调用,但是很快:
Req
是Asp.Net所使用的2个令人讨厌的Request类的简单包装器类,它们有很多重叠但未能共享基类。GetUid()
从请求cookie中获取访问者cookie(如果有)。ShortGuid
is a lot like this 最重要的是,PutCookie()
已被修改以参与此变通办法,例如:
var cookie = new HttpCookie(CookieName, sguid);
//cookie.Shareable = false;
// Cookies shouldn't be shared, but, we signal to vary the OutputCache instead
// of blowing up OutputCache
cookie.Expires = DateTime.UtcNow.AddYears(1);
response.SetCookie(cookie);