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?

Foi útil?

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
'=======================================================
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top