سؤال

أنا أكتب تطبيقا على شبكة الإنترنت سيسمح للمستخدم بالتصفح إلى صفحات ويب متعددة داخل موقع الويب تقديم بعض الطلبات. جميع المعلومات التي سيتم تخزين مدخلات المستخدم في كائن قمت بإنشائه. المشكلة هي أنني بحاجة إلى الوصول إلى هذا الكائن من أي جزء من موقع الويب وأنا لا أعرف حقا أفضل طريقة لإنجاز هذا. أعلم أن حل واحد هو استخدام متغيرات الجلسة ولكني لا أعرف كيفية استخدامها في ASP .NET MVC. وأين أعلن متغير الجلسة؟ هل هناك أي طريقة أخرى؟

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

المحلول

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

في Global.asax هوك حدث OnSessionStart

void OnSessionStart(...)
{
    HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}

من أي مكان في التعليمات البرمجية حيث الخاصية httpContext.current الخاص! = null يمكنك استراحة هذا الكائن. أفعل هذا بطريقة تمديد.

public static MySessionObject GetMySessionObject(this HttpContext current)
{
    return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}

بهذه الطريقة يمكنك في الكود

void OnLoad(...)
{
    var sessionObj = HttpContext.Current.GetMySessionObject();
    // do something with 'sessionObj'
}

نصائح أخرى

الجواب هنا صحيح، ومع ذلك، كافحت لتنفيذه في تطبيق ASP.NET MVC 3. أردت الوصول إلى كائن جلسة في وحدة تحكم ولم أتمكن من معرفة سبب الاحتفاظ في الحصول على "مثيل لم يتم تعيينه إلى مثيل خطأ كائن". ما لاحظته هو أنه في وحدة تحكم عندما حاولت الوصول إلى الجلسة من خلال القيام بما يلي، ظللت في الحصول على هذا الخطأ. هذا يرجع إلى حقيقة أن هذا. httpcontext هو جزء من كائن وحدة التحكم.

this.Session["blah"]
// or
this.HttpContext.Session["blah"]

ومع ذلك، ما أردت هو أن HttpContext أن هذا جزء من مساحة الاسم System.Web لأن هذه هي الإجابة أعلاه تقترح استخدامها في Global.asax.cs. لذلك اضطررت إلى القيام بما يلي صراحة:

System.Web.HttpContext.Current.Session["blah"]

ساعدني هذا، لست متأكدا مما إذا كنت قد فعلت أي شيء ليس مو هنا، لكنني آمل أن يساعد شخص ما!

لأنني لا أحب رؤية "httpcontext.current.session" حول المكان، فأنا أستخدم نمط singleton للوصول إلى متغيرات الجلسة، فإنه يمنحك سهولة الوصول إلى كيس مكتوب بشدة من البيانات.

[Serializable]
public sealed class SessionSingleton
{
    #region Singleton

    private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";

    private SessionSingleton()
    {

    }

    public static SessionSingleton Current
    {
        get
        {
            if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
            {
                HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
            }

            return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
        }
    }

    #endregion

    public string SessionVariable { get; set; }
    public string SessionVariable2 { get; set; }

    // ...

ثم يمكنك الوصول إلى بياناتك من أي مكان:

SessionSingleton.Current.SessionVariable = "Hello, World!";

إذا كنت تستخدم ASP.NET MVC، فإليك طريقة بسيطة للوصول إلى الجلسة.

من وحدة تحكم:

{Controller}.ControllerContext.HttpContext.Session["{name}"]

من وجهة نظر:

<%=Session["{name}"] %>

هذه هي بالتأكيد ليست أفضل طريقة للوصول إلى متغيرات الجلسة الخاصة بك، لكنها طريق مباشر. لذلك استخدمه بحذر (ويفضل أن يكون ذلك خلال النماذج الأولية السريعة)، واستخدم مجمع / حاوية و OnSessionStart عندما يصبح مناسبا.

هذر

حسنا، IMHO ..

  1. لا تشير أبدا إلى جلسة داخل صفحة العرض / الرئيسية
  2. تقليل useage الخاص بك من الجلسة. يوفر MVC Tempdata OBJ لهذا، وهو في الأساس جلسة تعيش رحلة واحدة إلى الخادم.

فيما يتعلق ب # 1، لدي طريقة عرض سيد مكتوبة بشدة والتي لديها خاصية للوصول إلى كل ما يمثل كائن الجلسة .... في مثلي، فإن العرض الرئيسي المكتوب من Stongly هو عام يعطيني بعض المرونة فيما يتعلق بصفحات العرض المكتوبة بشدة

ViewMasterPage<AdminViewModel>

AdminViewModel
{
    SomeImportantObjectThatWasInSession ImportantObject
}

AdminViewModel<TModel> : AdminViewModel where TModel : class
{
   TModel Content
}

وثم...

ViewPage<AdminViewModel<U>>

على الرغم من أنني لا أعرف عن ASP.NET MVC، ولكن هذا ما يجب أن نفعله في موقع .NET عادي. يجب أن تعمل من أجل ASP.NET MVC أيضا.

YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}

يمكنك وضع هذا داخل طريقة للوصول بسهولة. هذر

هناك 3 طرق للقيام بذلك.

  1. يمكنك الوصول مباشرة HttpContext.Current.Session

  2. يمكنك وهمية HttpContextBase

  3. إنشاء طريقة تمديد ل HttpContextBase

أنا أفضل الطريق الثالث. هذا الرابط مرجع جيد.

الحصول على / تعيين طرق جلسة httpccontext في basecontroller vs السخرية httpcontextbase لإنشاء طرق الحصول على / تعيين

إجابات رائعة من الرجال ولكني أحذرك من الاعتماد دائما على الجلسة. إنه سريع وسهل القيام بذلك، وبالطبع سيعمل ولكن لن يكون رائعا في جميع Cicrumstrances.

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

إذا كنت ترغب في حل مختلف، فيمكنك النظر في استخدام حاوية IOC مثل قلعة وندسور, ، إنشاء فئة موفر كغلاف ثم إبقاء مثيل واحد من صفك باستخدام أسلوب حياة لكل طلب أو دورة حياة الدورة حسب متطلباتك.

سوف تضمن IOC أن يتم إرجاع نفس الحالة في كل مرة.

أكثر تعقيدا نعم، إذا كنت بحاجة إلى حل بسيط فقط استخدم الجلسة.

فيما يلي بعض أمثلة التنفيذ أدناه من الاهتمام.

باستخدام هذه الطريقة يمكنك إنشاء فئة موفر على غرار:

public class CustomClassProvider : ICustomClassProvider
{
    public CustomClassProvider(CustomClass customClass)
    { 
        CustomClass = customClass;
    }

    public string CustomClass { get; private set; }
}

وتسجيله شيء مثل:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
            Component.For<ICustomClassProvider>().UsingFactoryMethod(
                () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
    }

طريقة الوصول إلى الجلسات هي كتابة فئة المساعد التي تغطي أسماء الحقول المختلفة وأنواعها. آمل أن يساعد هذا المثال:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;

namespace dmkp
{
    /// <summary>
    /// Encapsulates the session state
    /// </summary>
    public sealed class LoginInfo
    {
        private HttpSessionState _session;
        public LoginInfo(HttpSessionState session)
        {
            this._session = session;
        }

        public string Username
        {
            get { return (this._session["Username"] ?? string.Empty).ToString(); }
            set { this._session["Username"] = value; }
        }

        public string FullName
        {
            get { return (this._session["FullName"] ?? string.Empty).ToString(); }
            set { this._session["FullName"] = value; }
        }
        public int ID
        {
            get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
            set { this._session["UID"] = value; }
        }

        public UserAccess AccessLevel
        {
            get { return (UserAccess)(this._session["AccessLevel"]); }
            set { this._session["AccessLevel"] = value; }
        }

    }
}

يمكنك استخدام ViewModelbase كصف أساسي لجميع الطرز، سيعتني هذه الفئة بسحب البيانات من الجلسة

class ViewModelBase 
{
  public User CurrentUser 
  {
     get { return System.Web.HttpContext.Current.Session["user"] as User };
     set 
     {
        System.Web.HttpContext.Current.Session["user"]=value; 
     }
  }
}

يمكنك كتابة طريقة تمديد على HTTPCONTEXTBASE للتعامل مع بيانات الجلسة

T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null) 
{
    if(context.Session[key]!=null) 
    {
        return (T) context.Session[key];
    }
  else if(getFromSource!=null) 
  {
    var value = getFromSource();
   context.Session[key]=value; 
   return value; 
   }
  else 
  return null;
}

استخدم هذا مثل أدناه في وحدة تحكم

User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db  }); 

الحجة الثانية اختيارية سيتم استخدامها بيانات جلسة ملء لهذا المفتاح عندما تكون القيمة غير موجودة في الجلسة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top