我通常将它用于会话密钥,然后根据需要显式添加对象。这样做的原因是它是一种干净的方法,我发现您希望将会话中的对象数量保持在最低限度。
这种特殊的方法将表单身份验证和用户会话集中到一个地方,这样您就可以添加对象并忘记它。可以说这是一个很冗长的论点,但它确实可以防止任何重复,并且您不应该在会话中有太多对象。
以下内容可以存在于核心库中或您想要的任何地方。
/// <summary>
/// Provides a default pattern to access the current user in the session, identified
/// by forms authentication.
/// </summary>
public abstract class MySession<T> where T : class
{
public const string USERSESSIONKEY = "CurrentUser";
/// <summary>
/// Gets the object associated with the CurrentUser from the session.
/// </summary>
public T CurrentUser
{
get
{
if (HttpContext.Current.Request.IsAuthenticated)
{
if (HttpContext.Current.Session[USERSESSIONKEY] == null)
{
HttpContext.Current.Session[USERSESSIONKEY] = LoadCurrentUser(HttpContext.Current.User.Identity.Name);
}
return HttpContext.Current.Session[USERSESSIONKEY] as T;
}
else
{
return null;
}
}
}
public void LogOutCurrentUser()
{
HttpContext.Current.Session[USERSESSIONKEY] = null;
FormsAuthentication.SignOut();
}
/// <summary>
/// Implement this method to load the user object identified by username.
/// </summary>
/// <param name="username">The username of the object to retrieve.</param>
/// <returns>The user object associated with the username 'username'.</returns>
protected abstract T LoadCurrentUser(string username);
}
}
然后在以下命名空间到项目根目录的类中实现它(我通常将它放在 mvc 项目的代码文件夹中):
public class CurrentSession : MySession<PublicUser>
{
public static CurrentSession Instance = new CurrentSession();
protected override PublicUser LoadCurrentUser(string username)
{
// This would be a data logic call to load a user's detail from the database
return new PublicUser(username);
}
// Put additional session objects here
public const string SESSIONOBJECT1 = "CurrentObject1";
public const string SESSIONOBJECT2 = "CurrentObject2";
public Object1 CurrentObject1
{
get
{
if (Session[SESSIONOBJECT1] == null)
Session[SESSIONOBJECT1] = new Object1();
return Session[SESSIONOBJECT1] as Object1;
}
set
{
Session[SESSIONOBJECT1] = value;
}
}
public Object2 CurrentObject2
{
get
{
if (Session[SESSIONOBJECT2] == null)
Session[SESSIONOBJECT2] = new Object2();
return Session[SESSIONOBJECT2] as Object2;
}
set
{
Session[SESSIONOBJECT2] = value;
}
}
}
最后,在会话中显式声明您想要的内容的最大优点是您可以在 mvc 应用程序中的任何位置(包括视图)绝对引用它。只需参考它:
CurrentSession.Instance.Object1
CurrentSession.Instance.CurrentUser
再次比其他方法少一点通用性,但真的很清楚发生了什么,没有其他索具或依赖注入,并且对请求上下文 100% 安全。
另一方面,字典方法很酷,但你仍然会在所有地方使用字符串来引用东西。你可以用枚举或其他东西来操纵它,但我更喜欢强类型和设置并忘记上述方法。