I have a very subtle bug that I’m having trouble identifying.
Background:
We have 2 sites running off the same application on the same web server.
- SiteA — accessed by http://www.SiteA.com
- SiteB — accessed by http://www.SiteB.com
When the request first comes in, the siteId is identified based on the Host and stored in the Session as follows:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string host = Request.Url.Host;
int siteId = new SiteManager().GetSiteByUrl(host).SiteId;
if (SessionUser.Instance().SiteId != siteId)
{
SessionUser.Instance().SiteId = siteId;
}
}
This ID used later in determining what data to retreive and to determine what style to present:
// this happens during an initialization phase
_siteConfiguration = _siteManager.GetSiteById(SessionUser.Instance().SiteId);
// then later:
private void SetPageTheme()
{
string theme = null;
switch (_siteConfiguration.SiteId)
{
case ConfigurationHelper.SITE.A:
theme = "SiteATheme";
break;
case ConfigurationHelper.SITE.B:
theme = "SiteBTheme";
break;
}
Page.Theme = theme;
}
The problem:
the problem I’m facing is if you load both sites at almost exactly the same time, i.e. within milliseconds, sometimes SiteA will load with SiteB’s theme and vice versa. This doesn’t happen very often but it has come to the attention of the client so it’s now a problem.. Something is happening somewhere within those few milliseconds in the difference between SiteA loading and SiteB loading, and I don’t know how to identify what that is.
The question:
Does anyone have any ideas what could be going wrong here? Something is getting confused somewhere. Is it IIS mixing up the requests? Is it the Session mixing up the site it’s supposed to return the SiteId for?
If any more info is needed, I’ll supply it.
Update:
For reference, this is the definition of SessionUser (basically, create a static instance of an object to get the SiteId value from the Session):
public class SessionUser
{
private static SessionUser _instance;
public int SiteId { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public static SessionUser Instance()
{
if (null == _instance)
{
_instance = new SessionUser();
if (null != HttpContext.Current.Session)
{
if (null == HttpContext.Current.Session["User"])
{
if (HttpContext.Current.Request.QueryString["sid"] != null)
{
int nSiteId = int.Parse(HttpContext.Current.Request.QueryString["sid"]);
_instance.SiteId = nSiteId;
HttpContext.Current.Session["User"] = _instance;
}
}
else
{
_instance = (SessionUser) HttpContext.Current.Session["User"];
}
}
}
return _instance;
}
}
Without knowing what the ‘SessionUser’ class looks like, I can only speculate.
I will assume that SessionUser.Instance() returns a ‘static’ instance (or member rather).
Now, these will be shared across the entire application. So it makes sense that this cannot be shared between 2 sites.
I suggest you rather use
HttpContextto store the setting atBeginRequest.The code will then look like the following: