Domanda

invece di fare

 session("myvar1") = something
 session("myvar2") = something
 session("myvar3") = something
 session("myvar4") = something

sta facendo

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

sarebbe meglio?

È stato utile?

Soluzione

Invece di usare le costanti per le chiavi di sessione, sto usando il mio oggetto sessione di tipo sicuro, che assomiglia a questo (mi dispiace che sia in C #, vedi sotto per una versione 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; };
}

Ogni volta che devo leggere / scrivere qualcosa nella / dalla sessione, posso usare il mio oggetto sessione typesafe in questo modo:

string s = MySession.Current.MyString;
s = "new value";
MySession.Current.MyString = s;

Questa soluzione comporta numerosi vantaggi:

  • Ho una sessione typesafe (non più cast di tipi)
  • Posso documentare tutti i dati basati sulla sessione (commentando le proprietà pubbliche in MySession)
  • Quando si aggiunge un nuovo elemento alla sessione, non è necessario cercare la soluzione per verificare se la stessa chiave di sessione è già stata utilizzata altrove.

Aggiornamento: Ecco una versione VB (convertita automaticamente dalla versione C #). Siamo spiacenti, ma non conosco VB e quindi non sapevo come scrivere le proprietà in 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

Altri suggerimenti

Solo se quei valori sono correlati. Altrimenti usa semplici vecchie costanti.

Che ne dici di: -

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";
}

Questo ti permette di usare: -

session(SessionVar.myVar1) = something;

Ho usato classi come questa per creare un wrapper di sessione / cache tipizzato. Potrebbe essere necessario aggiungere un codice aggiuntivo per get / set, ma lo lascerò a te.

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;
        }
    }
}

Mi dispiace per il C # ....

Per la semplice rimozione di tutti i riferimenti alla chiave stringa, andrei con costanti globali statiche / condivise visibili nell'ambito dell'applicazione.

Altrimenti, il semplice wrapper fortemente tipizzato per le variabili di sessione è un'alternativa superiore ed è molto più adatto alle OOP considerando che si ottiene la compatibilità con intellisense e Object Browser.

L'unico modo in cui riesco a vedere l'enum di grande valore è quello di essere utilizzato per indicizzare in un array o in un elenco simile. Ma anche allora devi lanciare l'enum su un int.

Quindi, potresti avere un array che carichi all'avvio dell'applicazione con tutte le chiavi delle variabili di sessione e quindi un enum per gli indici. Tuttavia, dato che l'oggetto Session deriva da HttpSessionState, che deriva da IEnumerable, dovresti essere in grado di eseguire un ciclo foreach sulle variabili di sessione, se necessario.

Mi rendo conto che questa domanda è stata posta qualche tempo fa e una "risposta" è già stato scelto. Ma l'ho appena trovato. La risposta di Martin è buona. Tuttavia, per aiutare chiunque si imbatterà in questo in futuro, se vuoi davvero un modo semplice per gestire Session, leggi questo post . Non credo che troverai niente di più semplice.

Ho trovato una soluzione che evita alcuni svantaggi delle altre soluzioni pubblicate mantenendo intatta la struttura delle variabili Session. È semplicemente una scorciatoia sicura per ottenere e impostare variabili di sessione.

È C #, ma alla fine ho pubblicato alcuni VB.NET generati automaticamente.

Le migliori soluzioni che ho visto (la risposta accettata e quella di TheObjectGuy) richiedono una classe personalizzata che viene memorizzata in una variabile Session, quindi viene estratta dalla Session per accedere alle sue proprietà con qualcosa come MySessionClass.Current.MyProperty .

Il problema è che se stai utilizzando (o potresti utilizzare in futuro) qualcosa di diverso da una modalità InProc Session-State (vedi https://msdn.microsoft.com/en-us/library/ms178586%28v=vs.140%29.aspx ), l'intera classe dovrebbe passare attraverso la serializzazione per accedere a una singola proprietà.

Inoltre, ciò significa che perdi le implementazioni IEnumerable e ICollection offerte dalla Sessione effettiva, se ne hai bisogno. Con la mia soluzione, puoi semplicemente accedere alla sessione effettiva se hai bisogno di questa funzionalità.

Puoi facilmente usare queste variabili di sessione e sono di tipo sicuro. Può essere utilizzato insieme a istruzioni come Session [" MyProperty "], che consentiranno la conversione di un progetto esistente un riferimento alla volta. Quindi:

int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

diventa:

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

Ecco la classe attuale. CallerMemberName richiede .NET 4.5, ma anche se si utilizza una versione precedente è comunque possibile gestirlo passando esplicitamente propertyName. Inoltre, i tipi di proprietà devono essere nullable per farlo funzionare esattamente come le chiamate Session [" MyProp "] standard perché non impostate

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); } }
}

Ho persino scritto uno snippet di codice per facilitare l'aggiunta di queste proprietà:

<?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
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
'=======================================================
gt;(); } set { Set2<$type<*>gt;(value); } }]]> </Code> </Snippet> </CodeSnippet>

Sono un tipo C #, quindi questo VB.NET viene convertito automaticamente da http: //converter.telerik .com / :

<*>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top