строго типизированные сеансы в asp.net

Простите, если этот вопрос уже задавали. HttpContext.Current.Session["key"] возвращает объект, и нам нужно будет преобразовать его в этот конкретный Type, прежде чем мы сможем его использовать. Я смотрел различные реализации типизированных сессий

http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx

и я чувствовал, что нам нужно добавить еще немного кода (поправьте меня, если я ошибался) в SessionManager, если мы хотим добавить новый Type объекта в сеанс, либо как метод, либо как отдельную оболочку. Я думал, мы можем использовать дженерики

public static class SessionManager<T> where T:class
 {
  public void SetSession(string key,object objToStore)
  {
   HttpContext.Current.Session[key] = objToStore;
  }

  public T GetSession(string key)
  {
   return HttpContext.Current.Session[key] as T;
  }

 }
  • Есть ли неотъемлемое преимущество в использовании

    SessionManager<ClassType>.GetSession("sessionString")

чем использование

HttpContext.Current.Session["sessionString"] as ClassType
  • Я также подумал, что было бы неплохо иметь что-нибудь вроде

SessionManager["sessionString"] = objToStoreInSession, но обнаружил, что статический класс не может иметь индексатора. Есть ли другой способ добиться этого?

  • Моя мысль заключалась в создании SessionObject, который будет хранить Type и объект, а затем добавить этот объект в Session (используя SessionManager) с ключом. При извлечении приведите все объекты к SessionObject, получите тип (скажем, t) и объект (скажем, obj), приведите obj как t и верните его.

    public class SessionObject { public Type type {get;set;} public Object obj{get;set;}
    }

это тоже не сработает (так как обратная подпись будет такой же, но типы возврата будут разными).

Есть ли какой-либо другой элегантный способ сохранения / извлечения объектов в сеансе более безопасным способом


person ram    schedule 09.01.2010    source источник


Ответы (5)


Чтобы получить очень чистый, удобный и удобный способ работы с сеансом, посмотрите этот сообщение. Вы удивитесь, насколько это может быть просто.

person TheObjectGuy    schedule 10.01.2010
comment
хотя хороший пост, получение вашего класса из класса, специфичного для сеанса, не позволит вам получить свой класс из любого другого абстрактного класса / базового класса - person ram; 11.01.2010
comment
@Ram да, суть класса в моем сообщении в том, что это оболочка для любых элементов, которые вы хотите сохранить в сеансе. И, как я надеюсь, вы заметили, проще не может быть. - person TheObjectGuy; 11.01.2010
comment
Действительно ли это будет работать для внепроцессного состояния? Поскольку объект сеанса никогда не записывается обратно в хранилище сеанса, в хранилище сеанса по-прежнему будут храниться старые ранее сериализованные значения. - person David d C e Freitas; 04.11.2013
comment
@TheObjectGuy Ссылка в вашем ответе не работает. - person Tom Lint; 14.04.2016

Обратной стороной этого метода является то, что потребляющий код должен знать, какие ключи использовать для хранения и извлечения. Это может быть подвержено ошибкам, так как ключ должен быть точно правильным, иначе вы рискуете сохранить его в неправильном месте или получить обратно нулевое значение.

На самом деле я использую вариант со строгой типизацией, поскольку я знаю, что мне нужно в сеансе, и, таким образом, могу настроить класс упаковки в соответствии с требованиями. Я предпочитаю иметь дополнительный код в классе сеанса, и мне не нужно беспокоиться о ключевых строках где-либо еще.

person Grant Palin    schedule 11.01.2010
comment
Ага, согласен с тобой. Я вижу, что настройка SessionManager.Constants для строк сеанса как стандартная реализация, чтобы избежать опечаток - person ram; 11.01.2010

Вы можете просто использовать одноэлементный шаблон для своего объекта сеанса. Таким образом, вы можете смоделировать весь сеанс из одного объекта составной структуры. В этом сообщении говорится о том, о чем я говорю, и обсуждается объект Session как объект со слабой типизацией: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html

person allthingscs    schedule 25.03.2011

Фактически, если вы хотели ввести объекты, поместите тип на уровне метода, например:

public T GetValue<T>(string sessionKey)
{

}

Уровень класса больше, если у вас есть один и тот же объект в сеансе, но сеанс может расширяться до нескольких типов. Не знаю, беспокоился бы я об управлении сеансом; Я бы просто позволил ему делать то, что он делает, какое-то время, и просто предоставить средства для извлечения и сохранения информации в более строго типизированном виде (по крайней мере, для потребителя).

Да, индексы работать не будут; вместо этого вы можете создать его как экземпляр и сделать его статическим:

public class SessionManager
{
    private static SessionManager _instance = null;


    public static SessionManager Create()
    {
       if (_instance != null)
           return _instance;

       //Should use a lock when creating the instance
       //create object for _instance

       return _instance;
    }

    public object this[string key] { get { .. } }
}

Итак, это статическая реализация фабрики, но она также поддерживает единую точку контакта через статическую ссылку на класс диспетчера сеансов внутри. Каждый метод в sessionmanager может обернуть существующий сеанс ASP.NET или использовать ваше собственное внутреннее хранилище.

person Brian Mains    schedule 10.01.2010

Я опубликовал решение по вопросу StackOverflow стоит ли создать перечисление для имен ключей значений сеанса?

Я думаю, что это действительно здорово и содержит очень мало кода, чтобы это произошло. Он требует, чтобы .NET 4.5 был самым гладким, но это все еще возможно со старыми версиями.

Это позволяет:

int myInt = SessionVars.MyInt; 
SessionVars.MyInt = 3;

работать точно так:

int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;
person kevinpo    schedule 19.03.2015