Нужна помощь в выявлении незначительной ошибки .. в IIS? Сессия? В другом месте ..? - PullRequest
1 голос
/ 28 июля 2010

У меня очень тонкая ошибка, которую я не могу определить.

Справочная информация: У нас есть 2 сайта, на которых запущено одно и то же приложение на одном веб-сервере.

  • Сайт A - доступен по адресу www.SiteA.com
  • SiteB - доступ к www.SiteB.com

При первом поступлении запроса siteId идентифицируется на основе хоста и сохраняется в сеансе следующим образом:

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 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 смешивает запросы? Является ли Session смешиванием сайта, для которого он должен вернуть 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;
    }
}

Ответы [ 2 ]

4 голосов
/ 28 июля 2010

Не зная, как выглядит класс '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 голосов
/ 28 июля 2010

Полагаю, вы могли бы поместить код, хранящий текущий идентификатор сайта, в блок lock, но это может снизить производительность.Более разумно использовать что-то, не разделяемое обоими сайтами, как говорит Леппи .

Для примера блокировки:

if (SessionUser.Instance().SiteId != siteId)
{
    lock(somePrivateStaticObject)
    {
        if (SessionUser.Instance().SiteId != siteId)
        {
            SessionUser.Instance().SiteId = siteId;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...