هل هي فكرة جيدة لإنشاء التعداد الرئيسية أسماء الدورة القيم ؟

StackOverflow https://stackoverflow.com/questions/465522

سؤال

بدلا من القيام

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

يفعل

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

سيكون أفضل ؟

هل كانت مفيدة؟

المحلول

بدلا من استخدام الثوابت الدورة مفاتيح, أنا باستخدام بلدي نوع آمن الدورة الكائن الذي يبدو مثل هذا (آسف هذا هو في C# ، انظر أدناه للحصول على نسخة 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; };
}

كلما كنت في حاجة إلى قراءة/كتابة شيء من الدورة يمكنني استخدام بلدي typesafe كائن جلسة عمل مثل هذا:

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

هذا الحل النتائج في العديد من المزايا:

  • لدي typesafe الدورة (أي أكثر من نوع-يلقي)
  • أنا يمكن أن الوثيقة كل دورة على أساس البيانات (من خلال التعليق على الممتلكات العامة في MySession)
  • عند إضافة عنصر جديد إلى الدورة, أنا لم يكن لديك للبحث في حل للتحقق مما إذا كان نفس الجلسة الرئيسية التي كانت تستخدم بالفعل في مكان آخر.

تحديث: وهنا نسخة VB (تحويلها تلقائيا من C# الإصدار).آسف ولكن أنا لا أعرف VB و إذا لم تعرف كيف تكتب الخصائص في 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

نصائح أخرى

وفقط إذا كانت متعلقة تلك القيم. على خلاف ذلك استخدام الثوابت القديمة عادي.

وماذا عن: -

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

وهذا يتيح لك استخدام: -

session(SessionVar.myVar1) = something;

ولقد استعملت الطبقات مثل هذا لجعل كتبته المجمع الدورة / ذاكرة التخزين المؤقت. قد تحتاج إلى إضافة رمز إضافية إلى الحصول على / مجموعة، ولكن سأترك ذلك متروك لكم.

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

وعذرا عن C # ....

لشيء بسيط لإزالة كل من المراجع الرئيسية سلسلة، واود ان اذهب مع الثوابت العالمية ثابتة / المشتركة مرئية في نطاق التطبيق.

وإلا، مكتوب بشدة المجمع بسيط للمتغيرات جلسة هو بديلا ممتازا، وانها أبعد ما تكون أكثر بالنظر إلى أن تحصل التحسس ومستعرض الكائنات التوافق. دية صافية

والطريقة الوحيدة التي يمكنني أن أرى التعداد سلامة الكثير من القيمة لاستخدامها في مؤشر إلى صفيف أو قائمة مماثلة. ولكن حتى ذلك الحين عليك أن يلقي التعداد إلى int.

وهكذا، هل يمكن أن يكون مجموعة التي قمت بتحميل عند بدء تشغيل التطبيق مع كل من الجلسة مفاتيح متغير وبعد ذلك التعداد لالفهارس. ومع ذلك، بالنظر إلى أن الكائن Session مستمد من HttpSessionState، التي تستمد من IEnumerable، يجب أن تكون قادرة على القيام مجرد حلقة foreach على متغيرات جلسة، إذا كنت في حاجة إليها.

وأنا أدرك سئل هذا السؤال قبل قليل و "الجواب" تم التقاطها. ولكن أنا فقط جاء عبرها. الجواب مارتن جيدة. ومع ذلك، لمساعدة أي شخص يتعثر عبر هذا في المستقبل، إذا كنت تريد حقا وسيلة للتعامل مع بقعة الدورة، وهذا نصها <لأ href = "http://blog.theobjectguy.com/2009/12/session-with- style.html "يختلط =" نوفولو noreferrer "> آخر . أنا لا أعتقد أنك سوف تجد أي شيء أسهل.

لقد جاء مع الحل الذي يتجنب بعض العيوب من غيرها من الحلول التي نشرت عن طريق الحفاظ على هيكل الدورة المتغيرات سليمة.بل هو مجرد نوع آمن اختصار وتعيين متغيرات جلسة العمل.

إنها C#, ولكن لقد نشرت بعض السيارات ولدت VB.NET في نهاية المطاف.

أفضل الحلول التي رأيت (تقبل إجابة واحدة قبل TheObjectGuy) تتطلب فئة مخصصة التي تم تخزينها في متغير الدورة ، ومن ثم يتم سحبها من الدورة للوصول إلى خصائصه مع شيء من هذا القبيل MySessionClass.الحالي.MyProperty.

المشكلة مع ذلك هو أنه إذا كنت تستخدم حاليا (أو قد تستخدم في المستقبل) شيئا آخر غير InProc الدورة-وضع حالة (انظر https://msdn.microsoft.com/en-us/library/ms178586%28v=vs.140%29.aspx) ، كل فئة سوف تضطر إلى الذهاب من خلال التسلسل للوصول إلى خاصية واحدة.

أيضا هذا يعني أنك تفقد IEnumerable ICollection تطبيقات التي تقدمها الدورة الفعلية ، إذا كنت بحاجة إلى تلك.مع حل بي, يمكنك ببساطة الدخول الفعلي الدورة إذا كنت بحاجة إلى هذه الوظيفة.

يمكنك بسهولة استخدام هذه المتغيرات فهي من نوع آمن.أنها يمكن أن تستخدم جنبا إلى جنب مع البيانات مثل الدورة["MyProperty"], والتي سوف تسمح تحويل المشاريع القائمة مرجع واحد في كل مرة.لذلك:

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

يصبح:

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

هنا هو الدرجة الفعلية.على CallerMemberName يتطلب .NET 4.5, ولكن حتى إذا كنت تستخدم نسخة قديمة هل يمكن أن لا تزال إدارتها من قبل صراحة اجتياز propertyName.كذلك أنواع خصائص يجب أن يكون nullable لجعلها تعمل بالضبط نفس مستوى الدورة["MyProp"] يدعو لأن غير تعيين

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

حتى أنني كتبت مقتطف الشفرة لتسهيل إضافة هذه الخصائص:

<?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>

أنا C# الرجل لذا هذا VB.NET فقط لصناعة السيارات في تحويلها من قبل 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
'=======================================================
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top