2010-07-28 50 views
1

我有一个非常微妙的错误,我无法识别。需要帮助确定一个微妙的错误..在IIS中?会议?别处..?

背景: 我们有2个站点在同一个Web服务器上运行同一个应用程序。

  • 站点A - 通过访问www.SiteA.com
  • 网站B - 通过访问www.SiteB.com

当请求第一次进入时,网站ID是基于主机标识并存储在会话如下:

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; 
    } 
} 

此ID后在确定什么数据中检索并确定要呈现什么样式使用:

// 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; 
} 

问题:

我现在面临的问题是,如果您加载这两个网站在几乎正好在同一时间,在几毫秒内即有时站点A将与网站B的主题,反之亦然加载。这不经常发生,但它已经引起了客户的注意,所以现在它成了一个问题。在SiteA加载和SiteB加载之间的差异的几毫秒内发生了某些事情,我不知道如何确定是什么。

问题:

没有人有任何想法可能是想错了吗?某处在某处变得困惑。它是IIS混合请求?会话混合了它应该返回SiteId的网站吗?

如果需要更多信息,我会提供。

更新:

以供参考,这是SessionUser定义(基本上,创建一个对象的静态实例来获得从会话中SITEID值):

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; 
    } 
} 

回答

4

不知道'SessionUser'类看起来像什么,我只能推测。

我将假设SessionUser.Instance()返回一个'静态'实例(或者成员)。

现在,这些将在整个应用程序中共享。所以它是有道理的,这不能在2个网站之间共享。

我建议你宁愿用HttpContext来存储设置BeginRequest。然后

的代码如下所示:

class SessionUser 
{ 
    public static SessionUser Instance() 
    { 
    var ctx = HttpContext.Current; 
    var su = ctx["SessionUser"] as SessionUser; 
    if (su == null) 
    { 
     ctx["SessionUser"] = su = new SessionUser(); 
    } 
    return su; 
    } 
} 
+0

嗨leppie,我已经更新了与定义SessionUser代码的问题。 – DaveDev 2010-07-28 10:53:03

+0

@DaveDev:用我的替换那个巨大的混乱:)并删除那些'静态'领域! – leppie 2010-07-28 10:56:51

+0

我会非常乐意用你的代码替换那些代码 - 我的同事是'yoda程序员',所以这是他期待的典型代表!但我有一个问题 - 你的代码指定'class SessionUser'应该是'public class SessionUser'? – DaveDev 2010-07-28 11:04:36

0

我想你可以把一个存储lock块内的当前网站的ID代码,但是这可能会妨碍性能。使用两个站点不共享的内容更有意义,如leppie says

对于锁定例如:

if (SessionUser.Instance().SiteId != siteId) 
{ 
    lock(somePrivateStaticObject) 
    { 
     if (SessionUser.Instance().SiteId != siteId) 
     { 
      SessionUser.Instance().SiteId = siteId; 
     } 
    } 
} 
+0

这一切都很好,但你仍然会被下一次访问搞砸。 :) – leppie 2010-07-28 10:56:04

+0

@leppie:噢,我没有意识到这段代码在运行。我想这将需要在Page_Init或这东西工作... – 2010-07-28 11:01:17