每个用户的站点范围变量

时间:2014-06-10 18:24:47

标签: asp.net-mvc-4 global-variables

我有一个MVC4站点,需要在用户登录时(并且仅在用户登录时)维护一些信息。例如,一旦用户登录,我就会得到一个用户令牌'返回,允许我访问几个异地服务。

我尝试了两种不同的方法。第一种是使用访问用户会话的公共静态类。但是,在阅读静态类之后,我对使用它们犹豫不决。根据我读到的内容,静态类只应该用于只读对象,而我并没有这样使用它。虽然网站站点似乎在用户数量有限的情况下运行良好(目前已经有10个)。

(如果有人想向我解释为什么在MVC4中这是一个坏主意,请告诉我和/或链接到一篇文章)

public class SessionAccessorClasses
{
    public const string SessionAccessorSessionVariablesString = "_SessionAccessorSessionVariables";
    public static SessionAccessorModel SessionVariables
    {
        get { return System.Web.HttpContext.Current.Session != null ? (SessionAccessorModel)System.Web.HttpContext.Current.Session[SessionAccessorSessionVariablesString] : null; }
        set { System.Web.HttpContext.Current.Session.Add(SessionAccessorSessionVariablesString, value); }
    }
}

我的第二种(当前)方法是使用Session变量并使用全局可用类访问它们。

public class SessionAccessorClasses
{
    private const string SessionAccessorSessionVariablesString = "_SessionAccessorSessionVariables";
    public SessionAccessorModel GetSessionVariables()
    {
        return System.Web.HttpContext.Current.Session != null ? (SessionAccessorModel)System.Web.HttpContext.Current.Session[SessionAccessorSessionVariablesString] : null;
    }
    public void SetSessionVariables(SessionAccessorModel value)
    {
        System.Web.HttpContext.Current.Session.Add(SessionAccessorSessionVariablesString, value);
    }
    public void ClearSessionVariables()
    {
        System.Web.HttpContext.Current.Session.Remove(SessionAccessorSessionVariablesString);
    }
}

这样做很好,但是我称之为好,因为我不完全理解为什么公共静态类是如此糟糕,因为我现在必须在几乎开始时实例化我的新类每个函数,并在每个函数的末尾调用Set / Update函数;哪个感觉不对劲。

首先,由于我原来的静态类正在访问用户会话,它真的那么糟糕吗?

第二,我的第二课是更合适的做事方式吗?你能建议改进吗?

第三,如果没有别的,你能否给我这样做的积极/消极方面?

1 个答案:

答案 0 :(得分:1)

您想使用Session in ASP.net。它是为您描述的目的而创建的。

  

ASP.NET会话状态使您能够在用户在Web应用程序中导航ASP.NET页面时存储和检索用户的值。 HTTP是无状态协议。这意味着Web服务器将页面的每个HTTP请求视为独立请求。服务器不保留先前请求期间使用的变量值的知识。 ASP.NET会话状态在有限时间窗口内将来自同一浏览器的请求标识为会话,并提供了在该会话期间持久保存变量值的方法。默认情况下,为所有ASP.NET应用程序启用ASP.NET会话状态。

我是强类型可重用会话变量的粉丝,因此我编写了以下扩展来存储您想要创建的任何变量,而无需经常记住magic strings

public static class SessionExtensions
{
    public static bool TryGetValue<T>(this HttpSessionStateBase session, out T value) 
      where T : class
    {
        var name = typeof(T).FullName;

        value = session[name] as T;

        var result = value != null;

        return result;
    }

    public static void SetValue<T>(this HttpSessionStateBase session, T value)
    {
        var name = typeof(T).FullName;

        session[name] = value;
    }

    public static void RemoveValue<T>(this HttpSessionStateBase session)
    {
        var name = typeof(T).FullName;

        session[name] = null;
    }

    public static bool ValueExists(this HttpSessionStateBase session, Type objectType)
    {
        var name = objectType.FullName;

        var result = session[name] != null;

        return result;
    }
}

所以,如果你有一个班级:

public MyClass
{
  public int MyInt { get; set; }
}

您可以通过以下方式存储它:

Session.SetValue(MyClass);
  

需要在用户登录时(并且仅在用户登录时)维护一些信息。

可以通过几种方法更新这些方法以满足此要求。这是一种方式:

public static bool TryGetAuthenticatedValue<T>(this HttpSessionStateBase session, 
  out T value) 
  where T : class
{
    value = null;

    if (HttpContext.Current.User != null
        && HttpContext.Current.User.Identity != null
        && HttpContext.Current.User.IsAuthenticated)
    {
      var name = typeof(T).FullName;

      value = session[name] as T;
    }

    var result = value != null;

    return result;
}       

我还建议你在会话中存储的任何类都是可序列化的。也就是说它有一个无参数构造函数并标记为[Serializable]