asp.net - sessionstate - session variable c#
¿Es una buena idea crear una enumeración para los nombres clave de los valores de la sesión? (7)
En lugar de usar constantes para las claves de sesión, estoy usando mi propio objeto de sesión seguro para tipos, que se ve así (lo siento en C #, ver a continuación una versión de VB):
public class MySession
{
// Private constructor (use MySession.Current to access the current instance).
private MySession() {}
// Gets the current session.
public static MySession Current
{
get
{
MySession session = HttpContext.Current.Session["__MySession__"] as MySession;
if (session == null)
{
session = new MySession();
HttpContext.Current.Session["__MySession__"] = session;
}
return session;
}
}
// My session data goes here:
public string MyString { get; set; };
public bool MyFlag { get; set; };
public int MyNumber { get; set; };
}
Cada vez que necesito leer / escribir algo a / desde la sesión, puedo usar mi objeto de sesión typesafe como este:
string s = MySession.Current.MyString;
s = "new value";
MySession.Current.MyString = s;
Esta solución tiene varias ventajas:
- Tengo una Sesión segura (no más tipos de conversión)
- Puedo documentar todos los datos de la sesión (comentando las propiedades públicas en MySession)
- Al agregar un nuevo elemento a la sesión, no tengo que buscar en la solución para verificar si la misma clave de sesión ya se usó en otro lugar.
Actualización: Aquí hay una versión VB (convertida automáticamente desde la versión C #). Lo siento, pero no sé VB y no sabía cómo escribir las propiedades en VB:
Public Class MySession
'' Private constructor (use MySession.Current to access the current instance).
Private Sub New()
End Sub
'' Gets the current session.
Public Shared ReadOnly Property Current() As MySession
Get
Dim session As MySession = TryCast(HttpContext.Current.Session("__MySession__"), MySession)
If session = Nothing Then
session = New MySession()
HttpContext.Current.Session("__MySession__") = session
End If
Return session
End Get
End Property
'' My session data goes here:
Public MyString As String
Public MyFlag As Boolean
Public MyNumber As Integer
End Class
en lugar de hacer
session("myvar1") = something
session("myvar2") = something
session("myvar3") = something
session("myvar4") = something
está haciendo
enum sessionVar
myvar1
myvar2
myvar3
myvar4
end enum
session(sessionVar.myvar1.tostring) = something
session(sessionVar.myvar2.tostring) = something
session(sessionVar.myvar3.tostring) = something
session(sessionVar.myvar4.tostring) = something
¿seria mejor?
He usado clases como esta para hacer una envoltura de caché / sesión mecanografiada. Es posible que necesite agregar código adicional al get / set, pero lo dejo en sus manos.
internal class SessionHelper
{
private const string myVar1Key = "myvar1";
public static int MyVar1
{
get
{
return (int)System.Web.HttpContext.Current.Session[myVar1Key];
}
set
{
System.Web.HttpContext.Current.Session[myVar1Key] = value;
}
}
}
Perdón por el C # ...
Para simplificar la eliminación de todas las referencias de clave de cadena, iría con constantes estáticas / compartidas globales visibles en el alcance de la aplicación.
De lo contrario, el envoltorio simple fuertemente tipado para las variables de sesión es una alternativa superior, y es mucho más amigable con OOP, teniendo en cuenta que obtienes compatibilidad con Intellisense y Object Browser.
La única forma en que puedo ver que la enumeración tiene mucho valor es usarla para indexar en una matriz o una lista similar. Pero incluso entonces tienes que convertir la enumeración en int.
Por lo tanto, podría tener una matriz que cargue al inicio de la aplicación con todas sus claves de variable de sesión y luego una enumeración para los índices. Sin embargo, dado que el objeto Session se deriva de HttpSessionState, que se deriva de IEnumerable, debería poder hacer un bucle foreach sobre las variables de la sesión, si es necesario.
Qué tal si:-
public static class SessionVar
{
public static readonly string myVar1 = "myVar1";
public static readonly string myVar2 = "myVar2";
public static readonly string myVar3 = "myVar3";
public static readonly string myVar4 = "myVar4";
}
Esto le permite usar:
session(SessionVar.myVar1) = something;
Solo si esos valores están relacionados. De lo contrario, use constantes antiguas simples.
Me doy cuenta de que esta pregunta fue hecha hace un tiempo y ya se ha elegido una "respuesta". Pero acabo de encontrarlo. La respuesta de Martin es buena. Sin embargo, para ayudar a cualquier persona que se tope con esto en el futuro, si realmente desea una forma elegante de tratar con la Sesión, lea esta publicación . No creo que encuentres nada más fácil.
Se me ocurrió una solución que evita ciertas desventajas de las otras soluciones publicadas manteniendo intacta la estructura de las variables de Sesión. Es simplemente un atajo seguro para obtener y establecer variables de Sesión.
Es C #, pero publiqué algunos VB.NET autogenerados al final.
Las mejores soluciones que he visto (la respuesta aceptada y la de TheObjectGuy) requieren una clase personalizada que se almacena en una variable Session, y luego se extrae de la sesión para acceder a sus propiedades con algo como MySessionClass.Current.MyProperty.
El problema con esto es que si actualmente está utilizando (o puede usar en el futuro) algo distinto de un modo de estado de sesión InProc (consulte https://msdn.microsoft.com/en-us/library/ms178586%28v= vs.140% 29.aspx ), toda la clase debería pasar por la serialización para acceder a una sola propiedad.
Además, eso significa que pierde las implementaciones de IEnumerable e ICollection ofrecidas por la Sesión real, si las necesita. Con mi solución, puede simplemente acceder a la sesión real si necesita esta funcionalidad.
Puede usar fácilmente estas variables de sesión y son seguras para el tipo. Se puede usar junto con declaraciones como Session ["MyProperty"], que permitirán la conversión de un proyecto existente, una referencia a la vez. Asi que:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;
se convierte en:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
Aquí está la clase real. El CallerMemberName requiere .NET 4.5, pero incluso si está utilizando una versión anterior, aún puede administrarla al pasar explícitamente el propertyName. Además, los tipos de propiedades deben ser anulables para que actúen exactamente igual que las llamadas de sesión estándar ["MyProp"] porque no se establece
public static class SessionVars
{
private static T Get2<T>([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
if (HttpContext.Current.Session[propertyName] == null)
{
return default(T);
}
return (T)HttpContext.Current.Session[propertyName];
}
private static void Set2<T>(T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
HttpContext.Current.Session[propertyName] = value;
}
public static int MyInt { get { return Get2<int>(); } set { Set2<int>(value); } }
public static bool MyBool { get { return Get2<bool>(); } set { Set2<bool>(value); } }
public static string MyString { get { return Get2<string>(); } set { Set2<string>(value); } }
}
Incluso escribí un fragmento de código para facilitar la adición de estas propiedades:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>SessionVars Property</Title>
<Author>kevinpo</Author>
<Shortcut>sv</Shortcut>
<Description>Adds a property for use in a SessionVars class</Description>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<Default>int</Default>
</Literal>
<Literal>
<ID>property</ID>
<Default>PropertyName</Default>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[public static $type$ $property$ { get { return Get2<$type$>(); } set { Set2<$type$>(value); } }]]>
</Code>
</Snippet>
</CodeSnippet>
Soy un tipo de C #, por lo que este VB.NET se acaba de convertir automáticamente por http://converter.telerik.com/ :
Public NotInheritable Class SessionVars
Private Sub New()
End Sub
Private Shared Function Get2(Of T)(<System.Runtime.CompilerServices.CallerMemberName> Optional propertyName As String = "") As T
If HttpContext.Current.Session(propertyName) Is Nothing Then
Return Nothing
End If
Return DirectCast(HttpContext.Current.Session(propertyName), T)
End Function
Private Shared Sub Set2(Of T)(value As T, <System.Runtime.CompilerServices.CallerMemberName> Optional propertyName As String = "")
HttpContext.Current.Session(propertyName) = value
End Sub
Public Shared Property MyInt() As Integer
Get
Return Get2(Of Integer)()
End Get
Set
Set2(Of Integer)(value)
End Set
End Property
Public Shared Property MyBool() As Boolean
Get
Return Get2(Of Boolean)()
End Get
Set
Set2(Of Boolean)(value)
End Set
End Property
Public Shared Property MyString() As String
Get
Return Get2(Of String)()
End Get
Set
Set2(Of String)(value)
End Set
End Property
End Class
''=======================================================
''Service provided by Telerik (www.telerik.com)
''Conversion powered by NRefactory.
''Twitter: @telerik
''Facebook: facebook.com/telerik
''=======================================================