é uma boa idéia para criar uma enumeração para os nomes das teclas de valores de sessão?
-
19-08-2019 - |
Pergunta
em vez de fazer
session("myvar1") = something
session("myvar2") = something
session("myvar3") = something
session("myvar4") = something
está fazendo
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 melhor?
Solução
Em vez de usar constantes para as chaves de sessão, estou usando o meu próprio tipo seguro objeto de sessão, que se parece com isso (desculpe este é em C #, veja abaixo para uma versão 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; };
}
Sempre que eu preciso para ler / escrever algo de / para a sessão, eu posso usar o meu typesafe objeto de sessão como esta:
string s = MySession.Current.MyString;
s = "new value";
MySession.Current.MyString = s;
Esta solução resulta em várias vantagens:
- Eu tenho um typesafe sessão (não mais do tipo-casts)
- I pode documentar todos os dados da sessão com base (por comentar as propriedades públicas em MySession)
- Ao adicionar um novo elemento para a sessão, eu não tenho que procurar a solução para verificar se a mesma sessão-chave já foi usado em outro lugar.
Update: Aqui está uma versão VB (convertido automaticamente a partir da versão C #). Desculpe, mas eu não sei VB e então eu não sei como escrever as propriedades em 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
Outras dicas
Somente se esses valores estão relacionados. Caso contrário, use constantes antigos simples.
Como sobre: ??-
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";
}
Isso permite que você usar: -
session(SessionVar.myVar1) = something;
Eu usei classes como este para fazer um invólucro sessão / cache digitado. Você pode precisar adicionar código adicional para o get / set, mas vou deixar isso para você.
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;
}
}
}
Sorry about the C # ....
Para a coisa simples de remover todas as referências chave corda, eu iria com estáticos global / constantes compartilhadas visíveis no escopo de aplicativo.
Caso contrário, o invólucro simples fortemente tipado para variáveis ??de sessão é uma alternativa superior, e é muito mais OOP-friendly considerando que você começa intellisense e compatibilidade localizador de objectos.
A única maneira que eu posso ver a enumeração sendo de muito valor é para ser usado para o índice em uma matriz ou uma lista similar. Mas mesmo assim, você tem que lançar o enum para um int.
Assim, você pode ter uma matriz que você carrega na inicialização do aplicativo com todas as suas chaves variáveis ??de sessão e, em seguida, um enum para os índices. No entanto, dado que as deriva objeto de sessão de HttpSessionState, que deriva de IEnumerable, você deve ser capaz de simplesmente fazer um loop foreach sobre as variáveis ??da sessão, se você precisa.
Eu percebo esta pergunta foi feita há um tempo atrás e uma "resposta" já foi escolhido. Mas eu só vim através dele. A resposta de Martin é bom. No entanto, para auxiliar as pessoas que se depara com isso no futuro, se você realmente quer uma maneira lisa para lidar com Session, leia este pós . Eu não acho que você vai encontrar algo mais fácil.
Eu vim com uma solução que evite certas desvantagens das outras soluções postadas, mantendo a estrutura das variáveis ??de sessão intacta. É simplesmente um atalho tipo seguro para obter e definir variáveis ??de sessão.
É de C #, mas eu postei alguns VB.NET gerado automaticamente no final.
As melhores soluções que tenho visto (a resposta aceite e os um por TheObjectGuy) requerem uma classe personalizada que é armazenada em uma variável de sessão, e depois é retirado da sessão para acessar suas propriedades com algo como MySessionClass.Current.MyProperty .
O problema com isto é que se você está usando (ou pode usar no futuro) algo diferente de um modo InProc Session-State (veja https://msdn.microsoft.com/en-us/library/ms178586%28v=vs.140%29.aspx ), a classe inteira teria que passar por serialização para acessar uma única propriedade.
Além disso, isso significa que você perderá as implementações IEnumerable e ICollection oferecidos pela actual sessão, se você precisar deles. Com a minha solução, você pode simplesmente acessar o actual sessão se você precisar dessa funcionalidade.
Você pode facilmente usar essas variáveis ??de sessão e são de tipo seguro. Ele pode ser usado juntamente com declarações como Session [ "MyProperty"], o que permitirá a conversão de uma uma referência de projeto existente de cada vez. Assim:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;
torna-se:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
Aqui está a classe real. O CallerMemberName requer .NET 4.5, mas mesmo se você estiver usando uma versão mais antiga você ainda pode controlá-lo, passando explicitamente o propertyName. Além disso, os tipos de propriedades deve ser anulável para torná-lo agir exatamente a mesma Sessão padrão [ "MyProp"] chamadas porque um não-set
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); } }
}
Eu até escrevi um trecho de código para facilitar a adição dessas propriedades:
<?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>
Eu sou um C # cara, então este VB.NET é apenas auto-convertido 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
'=======================================================