在IIS中需要帮助识别一个微妙的bug?会议?别处..?

时间:2010-07-28 10:28:52

标签: c# asp.net debugging iis session

我有一个非常微妙的错误,我无法识别。

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

  • SiteA - 由www.SiteA.com访问
  • SiteB - 由www.SiteB.com访问

当请求首次出现时,将根据主机识别siteId并将其存储在Session中,如下所示:

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

问题:

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

问题:

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

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

更新

作为参考,这是SessionUser的定义(基本上,创建一个对象的静态实例以从Session获取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;
    }
}

2 个答案:

答案 0 :(得分:4)

不知道'SessionUser'类是什么样的,我只能推测。

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

现在,这些将在整个应用程序中共享。所以有意义的是,这不能在两个站点之间共享。

我建议您使用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;
  }
}

答案 1 :(得分:0)

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

对于锁定示例:

if (SessionUser.Instance().SiteId != siteId)
{
    lock(somePrivateStaticObject)
    {
        if (SessionUser.Instance().SiteId != siteId)
        {
            SessionUser.Instance().SiteId = siteId;
        }
    }
}
相关问题