Why cacheRolesinCookie does not work well with the Ajax Extensions 1.0 and RoleManager of .NET Framework 2.0?
One of my customers ran into this issue couple of months ago. I wanted to blog it earlier but I was waiting for the Fix to come out.
The typical scenario is - you are using the System.Web.RoleManager of .NET Framework 2.0 along with Ajax Extensions. When you do a callback you might run into exception as below (changed the names as required) -
Event Type: Warning
Event Source: ASP.NET 2.0.50727.0
Event Category: Web Event
Event ID: 1309
Date: 10/16/2007
Time: 11:24:13 PM
User: N/A
Computer: ABCD
Description:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 10/16/2007 11:24:12 PM
Event time (UTC): 10/17/2007 5:24:12 AM
Event ID: 3984df620d5148d58cfddc59a2c64559
Event sequence: 17219
Event occurrence: 95
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/12345/Root/Client-11-128370461828028786
Trust level: Full
Application Virtual Path: /Client
Application Path: C:\Inetpub\wwwroot\Test\
Machine name: ABCD
Process information:
Process ID: 4448
Process name: w3wp.exe
Account name: ABCD\ABCD
Exception information:
Exception type: HttpException
Exception message: Server cannot modify cookies after HTTP headers have been sent.
Request information:
Request URL: <https://Test/App_Themes/Default/Styles/Base.css>
Request path: /App_Themes/Default/Styles/Base.css
User host address: 71.123.134.143
User: ABCD@ABCD.com
Is authenticated: True
Authentication Type: Forms
Thread account name: ABCD\ABCD
Thread information:
Thread ID: 18
Thread account name: ABCD\ABCD
Is impersonating: False
Stack trace: at System.Web.HttpCookieCollection.Add(HttpCookie cookie)
at System.Web.Security.RoleManagerModule.OnLeave(Object source, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Custom event details:
For more information, see Help and Support Center at <https://go.microsoft.com/fwlink/events.asp>.
This comes up because you can’t send a set-cookie header after anything has been sent to the client.
Now the OnLeave event of RoleManager is set to be executed on App.EndRequest (Code taken from Reflector) –
public void Init(HttpApplication app)
{
if (Roles.Enabled)
{
app.PostAuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
}
And when you use Ajax, HTTP Headers are sent back to client before Application_End and this OnLeave event will try to modify the cookie if CacheRolesInCookie is true –
private void OnLeave(object source, EventArgs eventArgs)
{
if (Roles.Enabled && Roles.CacheRolesInCookie)
{
.......
.......
}
}
Since the content is flushed by the time that code runs and the code does not check if something is sent to client already, the exception comes up.
This issue has been fixed in the .NET Framework 3.5 release. It still doesn’t send the cookie, but you won’t throw an exception. The code looks like below -
private void OnLeave(object source, EventArgs eventArgs)
{
HttpApplication application = (HttpApplication) source;
HttpContext context = application.Context;
if (((Roles.Enabled && Roles.CacheRolesInCookie) && !context.Response.HeadersWritten) && (((context.User != null) && (context.User is RolePrincipal)) && context.User.Identity.IsAuthenticated))
{
.....
.....
}
}
There is no workaround for this issue in .NET Framework other than not using CacheRolesInCookie itself by setting it to false.
I hope this help!
Comments
- Anonymous
November 23, 2007
PingBack from http://msdnrss.thecoderblogs.com/2007/11/23/why-cacherolesincookie-does-not-work-well-with-the-ajax-extensions-10-and-rolemanager-of-net-framework-20/