ASP.NET MVC में सत्र चर


169

मैं एक वेब एप्लिकेशन लिख रहा हूं जो उपयोगकर्ता को कुछ अनुरोध करने वाली वेबसाइट के भीतर कई वेब पेजों पर ब्राउज़ करने की अनुमति देगा। सभी जानकारी जो उपयोगकर्ता इनपुट को एक ऑब्जेक्ट में संग्रहीत किया जाएगा जो मैंने बनाई थी। समस्या यह है कि मुझे इस ऑब्जेक्ट को वेबसाइट के किसी भी भाग से एक्सेस करने की आवश्यकता है और मुझे वास्तव में इसे पूरा करने का सबसे अच्छा तरीका नहीं पता है। मुझे पता है कि एक समाधान सत्र चर का उपयोग करना है, लेकिन मैं नहीं जानता कि उन्हें एस्प .net MVC में कैसे उपयोग किया जाए। और मैं सत्र चर कहां घोषित करूंगा? क्या कोई और तरीका है?


3
आप वेब साइट और वेब अनुप्रयोग अवधारणाओं को मिला रहे हैं ... वे एक ही चीज नहीं हैं।
एड्रिआनिको

1
डेटाबेस की आवश्यकता की तरह लगता है
Coops

जवाबों:


123

मुझे लगता है कि आप इस बारे में सोचना चाहेंगे कि क्या चीजें वास्तव में एक सत्र की स्थिति में हैं। यह कुछ ऐसा है जो मैं खुद को हर बार कर रहा हूं और यह पूरी तरह से एक अच्छा दृढ़ता से टाइप किया गया तरीका है, लेकिन सत्र के संदर्भ में चीजों को डालते समय आपको सावधान रहना चाहिए। सब कुछ नहीं होना चाहिए क्योंकि यह किसी उपयोगकर्ता का है।

in global.asax हुक ऑनस्सेशनस्टार्ट ईवेंट

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

32
यदि ASP MVC का उपयोग किया जा रहा है, तो HttpContext.Current.Session से वास्तविक सत्र ऑब्जेक्ट का उपयोग नहीं करना बेहतर है, लेकिन सिस्टम से नया HttpSessionStateWrapper और HttpSessionState.ase का उपयोग करने के लिए System.Web.Abstractions.dll का उपयोग करें फिर सत्र प्राप्त करने के लिए किसी फ़ैक्टरी या DI का उपयोग करें।
पॉल

6
आप सत्र चर के लिए कुछ कैसे असाइन करते हैं? (जैसा कि सिर्फ एक्सेस करने का विरोध किया गया है)
raklos

31
यह पता लगाने की कोशिश कर रहे लोगों के लिए कि "OnSessionStart" घटना क्या है और आप इसे कैसे "हुक" करते हैं, देखें stackoverflow.com/questions/1531125/…
सेफ्रॉन

5
@Paul क्या आप एक उदाहरण प्रदान करने में सक्षम हैं? मैं HttpSessionStateWrapper का उपयोग करने के किसी भी उदाहरण को खोजने के लिए प्रतीत नहीं कर सकता।
जोसेफ वुडवर्ड

4
@AjayKelkar इस टिप्पणी सूत्र ने सुझाव दिया "यदि ASP MVC का उपयोग किया जा रहा है, तो यह HttpContext.Current.Session से वास्तविक सत्र ऑब्जेक्ट का उपयोग नहीं करने के लिए बेहतर है, लेकिन नए HttpSessionState.rapper और HttpSessionStateBase का उपयोग करने के लिए" जो आपके उत्तर को बेहतर नहीं बताता है
Coops

48

यहाँ उत्तर सही है, फिर भी मैंने इसे 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"]

इससे मुझे मदद मिली, निश्चित नहीं कि अगर मैंने ऐसा कुछ किया जो एमओ के आसपास नहीं है, लेकिन मुझे आशा है कि यह किसी की मदद करता है!


6
System.Web.HttpContext.Current.Session ["blah"] = मूल्य
टॉमाज़ इनविविज़

21

क्योंकि मैं जगह के बारे में "HTTPContext.Current.Session" देखकर नापसंद करता हूं, मैं सत्र चर तक पहुंचने के लिए एक सिंगलटन पैटर्न का उपयोग करता हूं, यह आपको डेटा के दृढ़ता से टाइप किए गए बैग तक पहुंचने का एक आसान तरीका देता है।

[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!";

2
इसलिए इस वर्ग की दो ज़िम्मेदारियाँ हैं: एक ही उदाहरण को बनाए रखना, और चर को संग्रहित करना ... मैं एक सिंगलटन के लिए IOC कंटेनर का उपयोग करता।
जोवेन

1
यदि आपके पास पहले से ही एक सेटअप है, तो मैं शायद पूरी तरह से इंजेक्ट-सक्षम सत्र सेवा भी करूंगा, हालांकि, निरंतरता शायद सबसे बड़ा लाभ है, मैं इस कोड का उपयोग करने के लिए इच्छुक हूँ यदि आप चाहें तो छोटे फीचरसेट वेबैप्स .. वेबविज़ार्ड के लिए इस कोड का उपयोग कर सकते हैं।
Dead.Rabit

14

यदि आप asp.net mvc का उपयोग कर रहे हैं, तो यहां सत्र को एक्सेस करने का एक सरल तरीका है।

एक नियंत्रक से:

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

एक दृश्य से:

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

यह निश्चित रूप से आपके सत्र चर तक पहुंचने का सबसे अच्छा तरीका नहीं है, लेकिन यह एक सीधा मार्ग है। इसलिए सावधानी के साथ इसका उपयोग करें (अधिमानतः तेजी से प्रोटोटाइप के दौरान), और उचित होने पर एक Wrapper / कंटेनर और OnSessionStart का उपयोग करें।

HTH


2
हम्म .. जो सबसे अच्छा तरीका है? मैं नियंत्रक पर सत्र से ViewState को डेटा पास करना चाहिए, नहीं करना चाहिए?
र्रेडकट

2
और क्या आप इस पद्धति के अवरोधों की व्याख्या कर सकते हैं?
RredCat

1
मुझे लगता है कि उनका मतलब था कि पढ़ने / लिखने के तरीकों के लिए सबसे अच्छा है। संगामिति / थ्रेड उपयोग के आधार पर, आपको दौड़ की स्थिति से बचने के लिए उन पठन / लेखन विधियों में भी ताले की आवश्यकता हो सकती है।
डीपस्पेस101

13

खैर, IMHO ।।

  1. अपने दृश्य / मास्टर पृष्ठ के अंदर एक सत्र का संदर्भ कभी न दें
  2. सत्र का अपना उपयोग कम करें। MVC इसके लिए TempData obj प्रदान करता है, जो मूल रूप से एक सत्र है जो सर्वर की एकल यात्रा के लिए रहता है।

# 1 के संबंध में, मेरे पास एक दृढ़ता से टाइप किया गया मास्टर व्यू है जिसमें सत्र वस्तु का प्रतिनिधित्व करने के लिए जो कुछ भी है उसे एक्सेस करने के लिए एक संपत्ति है .... मेरे उदाहरण में, स्टॉन्गली टाइप किया गया मास्टर दृश्य जेनेरिक है जो मुझे दृढ़ता से टाइप किए गए देखें पृष्ठों के संबंध में कुछ लचीलापन देता है

ViewMasterPage<AdminViewModel>

AdminViewModel
{
    SomeImportantObjectThatWasInSession ImportantObject
}

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

और फिर...

ViewPage<AdminViewModel<U>>

7

हालाँकि मुझे asp.net mvc के बारे में पता नहीं है, लेकिन यह वह है जो हमें एक सामान्य .net वेबसाइट में करना चाहिए। यह asp.net mvc के लिए भी काम करना चाहिए।

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

आप इसे आसान पहुंच के लिए एक विधि के अंदर रखेंगे। HTH


7

इसे करने के 3 तरीके हैं।

  1. आप सीधे पहुंच सकते हैं HttpContext.Current.Session

  2. आप मॉक कर सकते हैं HttpContextBase

  3. के लिए एक विस्तार विधि बनाएँ HttpContextBase

मैं 3 तरह से पसंद करता हूं। यह लिंक अच्छा संदर्भ है।

Get / Set मेथड बनाने के लिए बेसकंट्रोलर बनाम मॉकिंग HttpContextBase में HttpContext सत्र तरीके प्राप्त करें / सेट करें


7

सत्रों तक पहुँचने का मेरा तरीका एक सहायक वर्ग लिखना है जो विभिन्न क्षेत्रों के नाम और उनके प्रकारों को बताता है। मुझे आशा है कि यह उदाहरण मदद करता है:

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

    }
}

मुझे आपका उत्तर पसंद है ... क्या आप आगे बता सकते हैं कि क्या चल रहा है ... और इस धागे पर अन्य उत्तरों के विपरीत बेहतर दृष्टिकोण क्यों है।
शेफ_कोड

6

लोगों के शानदार जवाब, लेकिन मैं आपको हमेशा सत्र पर भरोसा करने के खिलाफ सावधान करूंगा। ऐसा करना त्वरित और आसान है, और निश्चित रूप से काम करेगा लेकिन सभी cicrumstances में महान नहीं होगा।

उदाहरण के लिए यदि आप ऐसे परिदृश्य में भाग लेते हैं, जहाँ आपकी होस्टिंग सत्र उपयोग की अनुमति नहीं देती है, या यदि आप वेब फ़ार्म पर हैं, या साझा SharePoint एप्लिकेशन के उदाहरण में हैं।

यदि आप एक अलग समाधान चाहते हैं तो आप कैसल विंडसर जैसे आईओसी कंटेनर का उपयोग कर देख सकते हैं , एक रैपर के रूप में एक प्रदाता वर्ग बनाना और फिर अपनी आवश्यकताओं के आधार पर प्रति अनुरोध या सत्र जीवन शैली का उपयोग करके अपनी कक्षा का एक उदाहरण रखना।

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

4

आप सभी मॉडल के लिए बेस क्लास के रूप में 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  }); 

दूसरा तर्क वैकल्पिक है कि यह उस सत्र के लिए भरण सत्र डेटा का उपयोग करेगा जब मूल्य सत्र में मौजूद नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.