在ASP.NET MVC 4中,Session对象在一段时间后为null

时间:2014-03-24 19:28:39

标签: asp.net-mvc-4 session session-variables session-state session-timeout

我有Web应用程序ASP.NET MVC 4.当用户登录到应用程序时,我将他的信息作为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"/>

另外,我在每个检查会话值的控制器上都有过滤器。这是过滤器:

public class CheckSessionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext.Session["UserCtx"] == null)
        {
            FormsAuthentication.RedirectToLoginPage();
        }
    }
}

可能会出现此错误,因为我使用静态属性?

1 个答案:

答案 0 :(得分:0)

最近我开发了一个Web .NET应用程序,我将当前登录用户的信息存储到“静态”Session对象中,就像您的代码一样。

然而,我意识到这是一种老式的方法,与旧的ASP一起使用。现在,ASP.NET提供了一种更好的方法来处理用户对象。

您应该将标准Session对象覆盖为User,而不是使用HttpContext对象。我通过遵循这种方法替换了我的代码并且它完美地运行。

下面,我将回顾一下我所做的步骤 - 我建议你也这样做。

首先,您必须编写将存储有关用户所需信息的类。这是我的。

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,以便在用户登录之后,使用您在上一步中定义的自定义类型的对象替换当前User的{​​{1}}对象(见最后一条指令)。

HttpContext