Asp.net mvc 4 在ASP.NET MVC 4中,会话对象在一段时间后为空
我有一个web应用程序ASP.NETMVC4。当用户登录到应用程序时,我将他的信息作为类UserCtx的对象写入会话。之前,我创建了一个cookie:Asp.net mvc 4 在ASP.NET MVC 4中,会话对象在一段时间后为空,asp.net-mvc-4,session,session-variables,session-state,session-timeout,Asp.net Mvc 4,Session,Session Variables,Session State,Session Timeout,我有一个web应用程序ASP.NETMVC4。当用户登录到应用程序时,我将他的信息作为类UserCtx的对象写入会话。之前,我创建了一个cookie: public ActionResult executeLogin(LoginModel model) { if (ModelState.IsValid) { FormsAuthentication.SetAuthCookie(model.UserName, false);
public ActionResult executeLogin(LoginModel model)
{
if (ModelState.IsValid)
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
UserCtx userCtx = ds.SetUserCtx(model.UserName, model.Password);
Session["UserCtx"] = userCtx;
return Redirect(returnUrl ?? "/Offer");
}
else
{
return View("Index");
}
}
为了便于对会话中保存的对象进行操作,我创建了一个静态属性,我在应用程序中使用它:
public class UserCtx
{
public static UserCtx UserLogged
{
get
{
UserCtx userCtx = ((UserCtx)HttpContext.Current.Session["UserCtx"]);
return userCtx;
}
}
}
例如,我经常在视图中使用此属性:
@if (UserCtx.UserLogged.ADMIN)
{
@Html.Partial("_gvNetLogPartial")
}
然而,过了一段时间,这个变量是空的,但我真的不知道为什么会发生这种情况。此外,我在web.config中设置了超时:
<sessionState timeout="30"/>
出现此错误可能是因为我使用了静态属性 最近,我开发了一个Web.NET应用程序,将当前登录用户的信息存储到一个“静态”会话中,与您的代码完全相同 然而,我意识到这是一种老式的方法,与旧的ASP一起使用。现在,ASP.NET提供了处理用户对象的更好方法 您应该将标准的
User
对象重写为HttpContext
,而不是使用Session
对象。我用这种方法替换了我的代码,它工作得非常好
下面,我将重述我所做的步骤——我建议你也这样做
首先,您必须编写一个类来存储您需要的关于用户的信息。这是我的
public interface ICustomPrincipal : IPrincipal
{
string Email { get; set; }
string[] Roles { get; set; }
int[] SalesmenId { get; set; }
bool HasWritePermission { get; set; }
}
public class CustomPrincipalSerializeModel
{
public string Email { get; set; }
public string[] Roles { get; set; }
public int[] SalesmenId { get; set; }
public bool HasWritePermission { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
private IPrincipal principal;
public CustomPrincipal(IPrincipal principal, WindowsIdentity identity)
{
this.Identity = identity;
this.principal = principal;
}
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
//return (principal.IsInRole(role));
if (Roles == null)
return false;
return Roles.Contains(role);
}
public string Email { get; set; }
public string[] Roles { get; set; }
public int[] SalesmenId { get; set; }
public bool HasWritePermission { get; set; }
}
然后,编辑Global.asax,这样,在用户登录之后,您可以将当前HttpContext
的user
对象替换为您在上一步中定义的自定义类型的对象(请参阅最后一条说明)
受保护的无效WindowsAuthentication\u onAuthentication(对象源,WindowsAuthenticationEventArgs e)
{
if(e.Identity.IsAuthenticated&&null==Request.Cookies.Get(CookieName))
{
CustomPrincipalSerializeModel cp=新的CustomPrincipalSerializeModel();
字符串username=e.Identity.Name;
[...]
//设置当前用户的数据
cp.角色=[…];
cp.saleseminid=[…];
cp.电子邮件=[…];
cp.HasWritePermission=[…];
[...]
//序列化cookie
JavaScriptSerializer jss=新的JavaScriptSerializer();
字符串userData=jss.Serialize(cp);
FormsAuthenticationTicket Formsauthenticket=
新表格身份证(
1.
用户名,
日期时间,现在,
DateTime.Now.AddHours(10),//cookie将在10小时后过期
假,,
用户数据);
var encryptedTicket=FormsAuthentication.Encrypt(formsauthtticket);
//储存饼干
HttpCookie HttpCookie=新的HttpCookie(CookieName,encryptedTicket);
Response.Cookies.Add(httpCookie);
}
}
受保护的无效应用程序\u PostAuthenticateRequest(对象发送方,事件参数e)
{
CustomPrincipal newUser=新CustomPrincipal(用户,(WindowsIdentity)用户.Identity);
HttpCookie-authCookie=Context.Request.Cookies.Get(CookieName);
if(authCookie!=null)
{
FormsAuthenticationTicket FormsAuthenticationTicket=FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer jss=新的JavaScriptSerializer();
CustomPrincipalSerializeModel ret=jss.Deserialize(formsAuthenticationTicket.UserData);
newUser.Email=ret.Email;
newUser.Roles=ret.Roles;
newUser.SalesmenId=ret.SalesmenId;
newUser.HasWritePermission=ret.HasWritePermission;
}
其他的
{
newUser.Email=null;
newUser.Roles=null;
newUser.SalesmenId=null;
newUser.HasWritePermission=false;
}
Context.User=Thread.CurrentPrincipal=newUser;
}
public interface ICustomPrincipal : IPrincipal
{
string Email { get; set; }
string[] Roles { get; set; }
int[] SalesmenId { get; set; }
bool HasWritePermission { get; set; }
}
public class CustomPrincipalSerializeModel
{
public string Email { get; set; }
public string[] Roles { get; set; }
public int[] SalesmenId { get; set; }
public bool HasWritePermission { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
private IPrincipal principal;
public CustomPrincipal(IPrincipal principal, WindowsIdentity identity)
{
this.Identity = identity;
this.principal = principal;
}
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
//return (principal.IsInRole(role));
if (Roles == null)
return false;
return Roles.Contains(role);
}
public string Email { get; set; }
public string[] Roles { get; set; }
public int[] SalesmenId { get; set; }
public bool HasWritePermission { get; set; }
}
protected void WindowsAuthentication_OnAuthenticate(Object source, WindowsAuthenticationEventArgs e)
{
if (e.Identity.IsAuthenticated && null == Request.Cookies.Get(CookieName))
{
CustomPrincipalSerializeModel cp = new CustomPrincipalSerializeModel();
string username = e.Identity.Name;
[...]
// Set the data of the current user
cp.Roles = [...];
cp.SalesmenId = [...];
cp.Email = [...];
cp.HasWritePermission = [...];
[...]
// Serialize the cookie
JavaScriptSerializer jss = new JavaScriptSerializer();
string userData = jss.Serialize(cp);
FormsAuthenticationTicket formsAuthTicket =
new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddHours(10), // The cookie will expire in 10 hours
false,
userData);
var encryptedTicket = FormsAuthentication.Encrypt(formsAuthTicket);
// Store the cookie
HttpCookie httpCookie = new HttpCookie(CookieName, encryptedTicket);
Response.Cookies.Add(httpCookie);
}
}
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
CustomPrincipal newUser = new CustomPrincipal(User, (WindowsIdentity)User.Identity);
HttpCookie authCookie = Context.Request.Cookies.Get(CookieName);
if (authCookie != null)
{
FormsAuthenticationTicket formsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer jss = new JavaScriptSerializer();
CustomPrincipalSerializeModel ret = jss.Deserialize<CustomPrincipalSerializeModel>(formsAuthenticationTicket.UserData);
newUser.Email = ret.Email;
newUser.Roles = ret.Roles;
newUser.SalesmenId = ret.SalesmenId;
newUser.HasWritePermission = ret.HasWritePermission;
}
else
{
newUser.Email = null;
newUser.Roles = null;
newUser.SalesmenId = null;
newUser.HasWritePermission = false;
}
Context.User = Thread.CurrentPrincipal = newUser;
}