ASP.NET Cookies BUG - 多个cookie随机重复?

Nen*_*nad 10 asp.net iis cookies asp.net-mvc-4

在向线路写入响应流时,似乎在ASP.NET cookie处理中存在恼人的错误.Set-Cookie标题随机倍增.

我的示例设置是:IIS8 Express服务器上的ASP.NET MVC4,但在IIS7集成模式上发生同样的问题,我在2009年发现了关于同一问题IIS6的帖子.它似乎存在一段时间的问题.

例如,在Global.asax.cs中,我订阅BeginRequest事件并在事件处理程序中写入HttpResponse.Cookie集合:

public class MvcApplication : System.Web.HttpApplication
{
    public override void Init()
    {
        base.Init();
        BeginRequest += OnBeginRequest;
    }

    void OnBeginRequest(object sender, EventArgs e)
    {
        Response.Cookies.Set(new HttpCookie("OnBeginRequest", "0"));
    }
}
Run Code Online (Sandbox Code Playgroud)

这将两次输出"OnBeginRequest"Set-Cookie标头.但是,如果对所有HttpApplication事件(AuthenticateRequest,AcquireRequestState等等〜总共~20个事件)进行类似操作,则发送到浏览器的http响应的头部将写入大量重复项.这也很明显,事件之后,编写cookie会从乞讨开始.

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnMapRequestHandler=7; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnMapRequestHandler=7; path=/
Set-Cookie: OnPostMapRequestHandler=8; path=/
Set-Cookie: OnAcquireRequestState=9; path=/
Set-Cookie: OnPostAcquireRequestState=10; path=/
Set-Cookie: OnPreRequestHandlerExecute=11; path=/
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnMapRequestHandler=7; path=/
Set-Cookie: OnPostMapRequestHandler=8; path=/
Set-Cookie: OnAcquireRequestState=9; path=/
Set-Cookie: OnPostAcquireRequestState=10; path=/
Set-Cookie: OnPreRequestHandlerExecute=11; path=/
Set-Cookie: OnPostRequestHandlerExecute=12; path=/
Set-Cookie: OnReleaseRequestState=13; path=/
Set-Cookie: OnPostReleaseRequestState=14; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnMapRequestHandler=7; path=/
Set-Cookie: OnPostMapRequestHandler=8; path=/
Set-Cookie: OnAcquireRequestState=9; path=/
Set-Cookie: OnPostAcquireRequestState=10; path=/
Set-Cookie: OnPreRequestHandlerExecute=11; path=/
Set-Cookie: OnPostRequestHandlerExecute=12; path=/
Set-Cookie: OnReleaseRequestState=13; path=/
Set-Cookie: OnPostReleaseRequestState=14; path=/
Set-Cookie: OnUpdateRequestCache=15; path=/
Set-Cookie: OnPostUpdateRequestCache=16; path=/
Set-Cookie: OnLogRequest=17; path=/
Set-Cookie: OnPostLogRequest=18; path=/
Set-Cookie: OnEndRequest=19; path=/
Set-Cookie: OnBeginRequest=0; path=/
Set-Cookie: OnAuthenticateRequest=1; path=/
Set-Cookie: OnPostAuthenticateRequest=2; path=/
Set-Cookie: OnAuthorizeRequest=3; path=/
Set-Cookie: OnPostAuthorizeRequest=4; path=/
Set-Cookie: OnResolveRequestCache=5; path=/
Set-Cookie: OnPostResolveRequestCache=6; path=/
Set-Cookie: OnMapRequestHandler=7; path=/
Set-Cookie: OnPostMapRequestHandler=8; path=/
Set-Cookie: OnAcquireRequestState=9; path=/
Set-Cookie: OnPostAcquireRequestState=10; path=/
Set-Cookie: OnPreRequestHandlerExecute=11; path=/
Set-Cookie: OnPostRequestHandlerExecute=12; path=/
Set-Cookie: OnReleaseRequestState=13; path=/
Set-Cookie: OnPostReleaseRequestState=14; path=/
Set-Cookie: OnUpdateRequestCache=15; path=/
Set-Cookie: OnPostUpdateRequestCache=16; path=/
Set-Cookie: OnLogRequest=17; path=/
Set-Cookie: OnPostLogRequest=18; path=/
Set-Cookie: OnEndRequest=19; path=/
Set-Cookie: OnPreSendRequestContent=20; path=/
Set-Cookie: OnPreSendRequestHeaders=21; path=/
X-Powered-By: ASP.NET
Date: Mon, 20 May 2013 10:47:20 GMT
Content-Length: 4002
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,如果在1个事件处理程序中编写相同的cookie,然后在另一个事件处理程序中更新,则会在标题中显示具有不同值的重复项.

是否有任何设置或解决方法可以阻止此默认HttpResponse.Cookies收集行为?

Kev*_*art 5

影响IIS 7的错误可能与影响IIS6的错误不同。此bug已被固定为4.7,在问题,他的错误有以下ID: DevID 289778

背景

这是它的描述:在IIS7中,每次离开asp.net管道返回到IIS管道时,都会在需要时添加cookie标头。在集成模式下,您可以在大多数事件之间保留asp.net管道。

因此,当它根据需要写出cookie时,它会检查是否已删除任何cookie。如果没有,它将检查是否已添加任何cookie。如果是这样,它将为该Cookie添加标题。它还会检查是否已修改任何cookie。如果是这样,它将为其添加标题。在迭代cookie的同时,它会记录所有已修改的cookie。

如果删除了任何cookie或对其进行了修改,则它将删除所有Set-Cookie标头,并写出新的set。(或者至少尝试。如果已清除头文件,则显然这是不可能的。)

到目前为止,一切都很好。但是,在重新进入托管管道后,我们读回了所有响应头,并重新构造了响应cookie。这是必需的,因为某些非托管模块可能已添加了新的响应cookie。这样做时,它不会为从响应头复制的任何cookie设置添加标志。到目前为止,一切仍然很好,对吗?

错误

好吧,不完全是。每次将cookie添加到Response.Cookies集合(或从集合中删除)时,Request.Cookies都会完全重新加载集合,然后将响应cookie添加到集合中,HttpCookie再次在对象上设置添加标志。这是错误。这导致每次添加或删除任何其他cookie时,都会在每个响应cookie上设置“添加”标志。

这意味着,如果您不修改或删除任何cookie,但是您至少添加了一个cookie,那么先前在其他管道阶段添加的所有cookie将被复制。但是,如果更改任何cookie或从Response.Cookies集合中删除任何cookie ,则将消除以前发生的所有重复。

骇客解决方法

要解决此错误,只需添加和删除一些任意cookie,或在标头被写出的同一事件中修改cookie。通常情况下,这将是EndRequest,除非你使用Server.TransferServer.RedirectResponse.Flush,或Reponse.End(除非您设置的endReponse参数设置为false)的应用程序,在这种情况下,你必须在同一事件做任何地方,那些发生。另外,请不要忘记库中发生的任何事件或您使用的任何HttpModule。基本上,您只想向每个事件添加以下代码:

try{
   var guid=Guid.NewGuid();
   context.Response.Cookies.Add(new HttpCookie(guid.ToString(),string.Empty);
   context.Response.Cookies.Remove(guid.ToString());
}
catch(HttpException)
{
   //This means the headers were already written,
   //in which case we need not do anything.
}
Run Code Online (Sandbox Code Playgroud)


Jey*_*mov -1

当你给cookie设置任何值时,首先清除它,用.Clear()

var cookie = this.Request.Cookies.Get("MyCookie");
if (cookie == null)
{
   cookie = new HttpCookie("MyCookie");
   this.Response.Cookies.Add(cookie);
}
else
{
   cookie.Values.Clear();                       //crear firstly..
   cookie.Values.Add("AnyKey", "AnyValue");
}
Run Code Online (Sandbox Code Playgroud)