Global.asax中的HttpApplication.Context为null

时间:2015-12-30 15:45:00

标签: c# asp.net session sitefinity

引用此answer regarding regenerating new SessionID

我在Global.asax.cs中创建了这段代码:

        protected void Application_Start(object sender, EventArgs e)
        {
            Bootstrapper.Initialized += new EventHandler<ExecutedEventArgs>(Bootstrapper_Initialized);
        }

        void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs e)
        {
            if (e.CommandName == "Bootstrapped")
            {
                EventHub.Subscribe<ILoginCompletedEvent>(LoginCompletedEventVerification);
            }
        }


        private void LoginCompletedEventVerification(ILoginCompletedEvent evt)
        {
            if (evt.LoginResult == UserLoggingReason.Success)
            {
                var manager = new SessionIDManager();
                var oldId = manager.GetSessionID(Context);
                var newId = manager.CreateSessionID(Context);
                bool isAdd = false, isRedir = false;
                manager.SaveSessionID(Context, newId, out isRedir, out isAdd);
                var ctx = HttpContext.Current.ApplicationInstance;
                var mods = ctx.Modules;
                var ssm = (SessionStateModule)mods.Get("Session");
                var fields = ssm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
                SessionStateStoreData rqItem = null;
                SessionStateStoreProviderBase store = null;
                FieldInfo rqIdField = null, rqLockIdField = null, rqStateNotFoundField = null;
                foreach (var field in fields)
                {
                    if (field.Name.Equals("_store")) store = (SessionStateStoreProviderBase)field.GetValue(ssm);
                    if (field.Name.Equals("_rqId")) rqIdField = field;
                    if (field.Name.Equals("_rqLockId")) rqLockIdField = field;
                    if (field.Name.Equals("_rqSessionStateNotFound")) rqStateNotFoundField = field;
                    if ((field.Name.Equals("_rqItem")))
                    {
                        rqItem = (SessionStateStoreData)field.GetValue(ssm);
                    }
                }
                var lockId = rqLockIdField.GetValue(ssm);
                if ((lockId != null) && (oldId != null))
                {
                    store.ReleaseItemExclusive(Context, oldId, lockId);
                    store.RemoveItem(Context, oldId, lockId, rqItem);
                }
                rqStateNotFoundField.SetValue(ssm, true);
                rqIdField.SetValue(ssm, newId);
            }
        }

请记住,我正在使用Sitefinity Web应用程序进行开发。 每次我的应用程序在成功登录期间遇到LoginCompletedEventVerification时,Context都会显示为null。现在,我最初想要将此片段添加到Sitefinity LoginWidget,但实现这一点是另一回事。

我没有在代码示例中包含它,但我确实已经Session_Start触发创建应用程序的“购物车”。我只是在验证后尝试为购物车创建一个新的SessionID。

是否有理由在此活动期间无法获得Context的值?

提前致谢。我感谢任何建议或批评!

编辑: Sitefinity knowledge base article where I got my Bootstrapper_Initialized code

2 个答案:

答案 0 :(得分:4)

  

我没有在代码示例中包含它,但我确实有Session_Start   开火创建我的应用程序的“购物车”。我只是想   在身份验证后为购物车创建新的SessionID。

真是没有。忘记在Application_Start事件中访问HttpContext。

或者你可以在Application_BeginRequest中执行此操作:

private static object syncRoot = new object();
private static bool initialized = false;
public void Application_BeginRequest(object sender, EventArgs e)
{
    if (!initialized)
    {
        lock (syncRoot)
        {
            if (!initialized)
            {
                // Do your stuff here with HttpContext

                initialized = true;
            }
        }
    }
}

您应该注意的另一件事是,HttpContext将无法在您可能已生成的任何后台线程中使用,并且HTTP请求已在其中完成执行。因此,在尝试访问此HttpContext时,您应该非常小心。

答案 1 :(得分:1)

LoginCompletedEvent事件是同步的 - 它不在后台线程中触发,而是认证请求的一部分。您可以通过直接调用HttpContect.Current来访问当前上下文,或者由于您在Sitefinity应用程序的上下文中,您可以将Sitefinity包装器用于当前上下文:

var currentContext = SystemManager.CurrentHttpContext;