So this one was bugging the hell out of me excuse the pun. In the end I had to write an HttpHandler to look into the application cache and see what was going on.
Now this works for me but I haven't had the code live long enough to be 100% sure but worth a try. It's only few lines of code.
I also under Jaben's advice decided to create the forums under it's own app pool in IIS and make the YetAnotherForum.Net website into a C# web application. If you need advice on this PM me.
YAFProviders.YAFRoleProvider.cs has an override method GetRolesForUser() which puts the currents users role memberships into cache under a cache entry called 'YafRoleProvider-UserRoleDictionary-YetAnotherForum'. This code only runs if the user's Session["UserUpdated"] == null i.e. user has just logged in or no activity for say 20 mins (server specific) and IIS has dropped the session.
I'm not sure why but when 'YafRoleProvider-UserRoleDictionary-YetAnotherForum' is dropped out of cache it doesn't always get recreated. So this is how I fixed the issue.
This code belongs inside InitUserAndPage() method,
1.9.3 alpha (YAF.Base.ForumPage.cs)
1.9.3 beta to RC2 (YAF.Classes.Utils.Context.cs)
Original code
if (user != null && Session["UserUpdated"] == null)
{
RoleMembershipHelper.UpdateForumUser(user, PageContext.PageBoardID);
Session["UserUpdated"] = true;
}
Amended code
if (user != null && Session["UserUpdated"] == null)
{
RoleMembershipHelper.UpdateForumUser(user, PageContext.PageBoardID);
Session["UserUpdated"] = true;
}
else if (user != null)
{
string[] roles = System.Web.Security.Roles.GetRolesForUser(user.UserName);
}
There shouldn't be any real additional overhead for performance because the method simply checks the cache to see if it exists. If no entry it recreates it and returns the roles as a string array.
I will let Jaben and other more experienced developers discuss why. It's just a quick and simple fix (for me) I hope it might help some of you guys. But it makes sense that if the roles are not present and were before access would be an issue. Hopefully it's as simple as this but maybe not!
CJ
P.S.
This is the code to create the HttpHandler, create the class in its own class library and then add a reference to the website or web application (YetAnotherForum.Net)
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.Security;
using System.Collections;
using System.IO;
namespace CachingManagerTool
{
public class CacheManager : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
string output = string.Empty;
IDictionaryEnumerator enumerator = context.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
output += context.Cache[enumerator.Key as string];
Type t = enumerator.Value.GetType();//You could write out the cache I just wanted a point to debug and watch the value and key.
}
}
#endregion
}
}
Put this in the web.config
To look at the cache set a break point in the CacheManager.cs and then in the brower url replace default.aspx with cache.axd and hit return. If you are in debug mode you should hit the break point and be able to look in your cache. Good luck
Edited by user
16 years ago |
Reason: amended how to debug cache