Обычно я использую это для ключа сеанса, а затем явно добавляю объекты по мере необходимости. Причина этого в том, что это чистый способ сделать это, и я считаю, что вы хотите, чтобы количество объектов в сеансе было минимальным.
Этот конкретный подход объединяет аутентификацию и сеанс пользователя в одном месте, чтобы вы могли добавлять объекты и забывать об этом. Можно было бы утверждать, что он большой многословный, но он предотвращает любое двойное увеличение, и вы не должны иметь слишком много объектов в сеансе.
В базовой библиотеке или в любом месте, где захотите, может существовать следующее.
/// <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% гарантией безопасности в контексте запроса.
В другом примечании, приближения dicionary - это круто, но вы все равно в конце концов со строками повсюду, чтобы ссылаться на вещи. Вы могли бы установить его с перечислениями или чем-то еще, но я предпочитаю сильную типизацию и задаю и забываю о вышеупомянутом подходе.
Что произойдет, если вы передадите один и тот же тип более чем одному контроллеру? Один сеанс перезапишет другой? – 2009-11-10 20:17:02
Нет, они оба будут иметь одинаковое имя типа и, таким образом, один и тот же ключ сеанса. Объекты сеанса не будут заменены, они будут только одним и тем же объектом на обоих контроллерах. –
Ответ добавлен ниже, который не требует базовых контроллеров и может даже получить доступ к сеансу в виде кода. – Gats