引用此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
答案 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;