Asp.net mvc 4 在ASP.NET MVC 4中,会话对象在一段时间后为空

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

我有一个web应用程序ASP.NETMVC4。当用户登录到应用程序时,我将他的信息作为类UserCtx的对象写入会话。之前,我创建了一个cookie:

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