Kontynuacja tego, co powiedzieli inni. Zwykle mam dwie warstwy:
Warstwa rdzeniowa. Znajduje się w bibliotece DLL, która jest dodawana do prawie wszystkich projektów aplikacji sieci Web . W tym mam klasę SessionVars, która wykonuje podstawową pracę dla pobierających / ustawiających stan sesji. Zawiera kod podobny do następującego:
public class SessionVar
{
static HttpSessionState Session
{
get
{
if (HttpContext.Current == null)
throw new ApplicationException("No Http Context, No Session to Get!");
return HttpContext.Current.Session;
}
}
public static T Get<T>(string key)
{
if (Session[key] == null)
return default(T);
else
return (T)Session[key];
}
public static void Set<T>(string key, T value)
{
Session[key] = value;
}
}
Zwróć uwagę na ogólne zasady uzyskiwania dowolnego typu.
Następnie dodaję również Getters / Setters dla określonych typów, zwłaszcza stringów, ponieważ często wolę pracować z string.Empty zamiast null dla zmiennych prezentowanych Użytkownikom.
na przykład:
public static string GetString(string key)
{
string s = Get<string>(key);
return s == null ? string.Empty : s;
}
public static void SetString(string key, string value)
{
Set<string>(key, value);
}
I tak dalej...
Następnie tworzę opakowania, aby to wyodrębnić i przenieść do modelu aplikacji. Na przykład, jeśli mamy dane klienta:
public class CustomerInfo
{
public string Name
{
get
{
return SessionVar.GetString("CustomerInfo_Name");
}
set
{
SessionVar.SetString("CustomerInfo_Name", value);
}
}
}
Masz rację? :)
UWAGA: Właśnie pomyślałem, dodając komentarz do zaakceptowanej odpowiedzi. Zawsze upewnij się, że obiekty można serializować podczas przechowywania ich w sesji podczas korzystania z serwera stanu. Próba zapisania obiektu przy użyciu typów generycznych na farmie internetowej może być zbyt łatwa i szybko się rozwija. Wdrażam na farmie internetowej w pracy, więc dodałem kontrole do mojego kodu w warstwie podstawowej, aby zobaczyć, czy obiekt jest możliwy do serializacji, kolejna korzyść z hermetyzowania metod pobierających i ustawiających sesje :)
HttpSessionState
/HttpContext
. Czy musisz zainstalować bibliotekę MVC w bibliotece DLL, aby zaimportować odpowiednie przestrzenie nazw?Tak właśnie robisz. Istnieje jednak krótsza składnia, której możesz użyć.
sSession = (string)Session["variable"] ?? "set this";
To znaczy, że jeśli zmienne sesji mają wartość null, ustaw sSession na „ustaw to”
źródło
Może sprawić, że rzeczy będą bardziej eleganckie, jeśli zostaną umieszczone w nieruchomości.
string MySessionVar { get{ return Session["MySessionVar"] ?? String.Empty; } set{ Session["MySessionVar"] = value; } }
wtedy możesz traktować go jako ciąg.
if( String.IsNullOrEmpty( MySessionVar ) ) { // do something }
źródło
Notacja „as” w języku c # 3.0 jest bardzo czysta. Ponieważ wszystkie zmienne sesji są obiektami dopuszczającymi wartość null, umożliwia to pobranie wartości i umieszczenie jej we własnej zmiennej wpisanej bez obawy o rzucenie wyjątku. W ten sposób można obsługiwać większość obiektów.
string mySessionVar = Session["mySessionVar"] as string;
Moja koncepcja polega na tym, że należy przeciągnąć zmienne sesji do zmiennych lokalnych, a następnie odpowiednio je obsługiwać. Zawsze zakładaj, że zmienne sesji mogą mieć wartość null i nigdy nie rzutuj ich na typ, który nie dopuszcza wartości null.
Jeśli potrzebujesz zmiennej wpisanej bez wartości null, możesz użyć TryParse, aby to uzyskać.
int mySessionInt; if (!int.TryParse(mySessionVar, out mySessionInt)){ // handle the case where your session variable did not parse into the expected type // e.g. mySessionInt = 0; }
źródło
Moim zdaniem najłatwiejszym sposobem na zrobienie tego, który jest jasny i łatwy do odczytania, jest:
String sVar = (string)(Session["SessionVariable"] ?? "Default Value");
Może nie jest to najbardziej wydajna metoda, ponieważ rzutuje domyślną wartość ciągu nawet w przypadku domyślnej (rzutowanie łańcucha jako ciągu), ale jeśli uczynisz to standardową praktyką kodowania, okaże się, że działa ona dla wszystkich typów danych, i jest łatwo czytelny.
Na przykład (całkowicie fałszywy przykład, ale pokazuje o co chodzi):
DateTime sDateVar = (datetime)(Session["DateValue"] ?? "2010-01-01"); Int NextYear = sDateVar.Year + 1; String Message = "The Procrastinators Club will open it's doors Jan. 1st, " + (string)(Session["OpeningDate"] ?? NextYear);
Podoba mi się opcja Generics, ale wydaje mi się, że to przesada, chyba że spodziewasz się, że będzie to potrzebne w każdym miejscu. Metodę rozszerzeń można zmodyfikować, aby specjalnie rozszerzyć obiekt Session, tak aby miała „bezpieczną” opcję get, taką jak Session.StringIfNull („SessionVar”) i Session [„SessionVar”] = „myval”; Łamie prostotę dostępu do zmiennej poprzez Session ["SessionVar"], ale jest to czysty kod i nadal pozwala na sprawdzanie wartości null lub string, jeśli jest to potrzebne.
źródło
Sprawdzanie niczego / wartości Null jest sposobem na zrobienie tego.
Radzenie sobie z typami obiektów nie jest właściwą drogą. Zadeklaruj ścisły typ i spróbuj rzutować obiekt na właściwy typ. (I użyj podpowiedzi rzutowej lub Konwertuj)
private const string SESSION_VAR = "myString"; string sSession; if (Session[SESSION_VAR] != null) { sSession = (string)Session[SESSION_VAR]; } else { sSession = "set this"; Session[SESSION_VAR] = sSession; }
Przepraszam za wszelkie naruszenia składni, jestem codziennym VB'erem
źródło
Zazwyczaj tworzę SessionProxy z silnie wpisanymi właściwościami dla elementów w sesji. Kod, który uzyskuje dostęp do tych właściwości, sprawdza wartość null i wykonuje rzutowanie na odpowiedni typ. Fajną rzeczą w tym jest to, że wszystkie moje elementy związane z sesjami są przechowywane w jednym miejscu. Nie muszę się martwić używaniem różnych kluczy w różnych częściach kodu (i zastanawiam się, dlaczego to nie działa). A dzięki wstrzykiwaniu zależności i mockowaniu mogę w pełni przetestować to za pomocą testów jednostkowych. Jeśli przestrzega zasad DRY, a także pozwala mi zdefiniować rozsądne wartości domyślne.
public class SessionProxy { private HttpSessionState session; // use dependency injection for testability public SessionProxy( HttpSessionState session ) { this.session = session; //might need to throw an exception here if session is null } public DateTime LastUpdate { get { return this.session["LastUpdate"] != null ? (DateTime)this.session["LastUpdate"] : DateTime.MinValue; } set { this.session["LastUpdate"] = value; } } public string UserLastName { get { return (string)this.session["UserLastName"]; } set { this.session["UserLastName"] = value; } } }
źródło
Lubię też zawijać zmienne sesji we właściwościach. Setery są tutaj trywialne, ale lubię pisać metody get, więc mają tylko jeden punkt wyjścia. Aby to zrobić, zwykle sprawdzam wartość null i ustawiam ją na wartość domyślną przed zwróceniem wartości zmiennej sesji. Coś takiego:
string Name { get { if(Session["Name"] == Null) Session["Name"] = "Default value"; return (string)Session["Name"]; } set { Session["Name"] = value; } }
}
źródło
Ta metoda również nie zakłada, że obiekt w zmiennej Session jest łańcuchem
if((Session["MySessionVariable"] ?? "").ToString() != "") //More code for the Code God
Zasadniczo zastępuje zmienną null pustym ciągiem przed przekształceniem jej w łańcuch, ponieważ
ToString
jest częściąObject
klasyźródło
Jeśli wiesz, że jest to ciąg, możesz użyć funkcji String.IsEmptyOrNull ().
źródło
Czy używasz platformy .NET 3.5? Utwórz metodę rozszerzenia IsNull:
public static bool IsNull(this object input) { input == null ? return true : return false; } public void Main() { object x = new object(); if(x.IsNull) { //do your thing } }
źródło
w ten sposób można sprawdzić, czy taki klucz jest dostępny
if (Session.Dictionary.ContainsKey("Sessionkey")) --> return Bool
źródło