ASP.Net MVC नियंत्रक कंस्ट्रक्टर्स में सत्र नल


88

क्यों कंट्रोलर्स के कंस्ट्रक्टर्स में सत्र शून्य है? इसे एक्शन विधियों से एक्सेस किया जा सकता है। मुमकिन है, क्योंकि एमवीसी राउटिंग फ्रेमवर्क एक नियंत्रक को नया करने के लिए जिम्मेदार है, यह सिर्फ उस बिंदु पर सत्र को तत्काल (फिर से) नहीं करता है।

क्या किसी को पता है कि यह डिजाइन द्वारा है और, यदि हां, तो क्यों?

[मैं एक आलसी लोड हो रहा है पैटर्न का उपयोग करके समस्या को दरकिनार करने में कामयाब रहा।]

जवाबों:


79

आंद्रेई सही है - यह अशक्त है क्योंकि जब ASP.NET MVC फ्रेमवर्क के तहत चल रहा है, तो HttpContext (और इसलिए HttpContext.Session) सेट नहीं है जब नियंत्रक वर्ग आपके द्वारा अपेक्षित के रूप में बाधित हो जाता है, लेकिन यह बाद में ("इंजेक्शन") सेट हो जाता है नियंत्रक वर्ग द्वारा। यदि आप जीवनचक्र की बेहतर समझ चाहते हैं, तो आप ASP.NET MVC फ्रेमवर्क (स्रोत उपलब्ध है) को नीचे खींच सकते हैं या इसका संदर्भ ले सकते हैं: यह पृष्ठ

यदि आपको सत्र का उपयोग करने की आवश्यकता है, तो एक तरीका "ऑनएशन एक्जिक्यूटिंग" विधि को ओवरराइड करना होगा और वहां तक ​​पहुंचना होगा, क्योंकि यह उस समय तक उपलब्ध होगा।

हालाँकि, जैसा कि आंद्रेई सुझाव दे रहा है, यदि आपका कोड सत्र पर निर्भर है, तो इकाई परीक्षण लिखना संभवतः मुश्किल हो सकता है, इसलिए शायद आप एक सहायक वर्ग में सत्र को लपेटने पर विचार कर सकते हैं जो तब एक अलग, गैर के लिए स्वैप किया जा सकता है। इकाई परीक्षणों के तहत चलने पर वेब संस्करण, इसलिए वेब से अपने नियंत्रक को डी-कपलिंग करना।


3
मुझे यकीन नहीं है कि यह HttpContext के बारे में उचित कथन है। यह वास्तव में पूरे प्रवाह की शुरुआत में सही निर्माण किया। आप यहाँ विस्तृत प्रवाह के बारे में थोड़ा पढ़ सकते हैं beletsky.net/2011/06/inside-aspnet-mvc-route-to-mvchanlder.html या आप रिफ्लेक्टर का उपयोग कर सकते हैं और अपने आप को पा सकते हैं जब httpContext को तत्काल किया गया है। .cs।
एलेक्सी शॉर्बक

@AlexeyShcherbak यह पहले से ही निर्मित हो सकता है - ओपी इस बारे में है कि क्या यह एमवीसी नियंत्रक की संपत्ति पर निर्धारित किया गया है। यानी सार्वजनिक HttpSessionStateBase सत्र {मिलता है; } System.Web.Mvc.Controller पर ये अलग चीजें हैं।
मेमेडेवेलर

61

यहां अन्य उत्तरों के अलावा, जबकि Controller.Sessionनिर्माणकर्ता में आबादी नहीं है, आप अभी भी सत्र को एक्सेस कर सकते हैं:

System.Web.HttpContext.Current.Session

मानक चेतावनी के साथ यह संभावित रूप से आपके नियंत्रक की परीक्षा को कम करता है।


3
इन दो सत्र गुणों में से प्रत्येक के लिए प्रकार भिन्न होता है, जो कि यदि आप सत्र राज्य के लिए एक संदर्भ रखना चाहते हैं, तो यह महत्वपूर्ण हो सकता है।
ब्रायनकॉसी

@BrianCooksey क्या अलग है?
माइकलमैओ

1
Controller.Session प्रकार System.Web.HttpSessionStateBase की है (देखें msdn.microsoft.com/en-us/library/... ), लेकिन System.Web.HttpContext.Current.Session (देखें प्रकार System.Web.SessionState.HttpSessionState की है MSDN .microsoft.com / en-us /
Library

पुराना उत्तर, लेकिन कहना चाहता था कि वीएस2019 एमवीसी इंस्टेंक्टर में System.Web.HttpContext.Current.Sessionभी nullहै।
jp2code

11

जीवन-चक्र में सत्र बाद में इंजेक्ट किया जाता है। वैसे भी आपको कंस्ट्रक्टर में सत्र की आवश्यकता क्यों है? यदि आपको टीडीडी के लिए इसकी आवश्यकता है, तो आपको सत्र को एक नकली वस्तु में लपेट देना चाहिए।


1
आंद्रेई रिनिया को जोड़ने के लिए, यह उनके द्वारा उल्लिखित तकनीक का एक विशिष्ट उदाहरण है: iridescence.no/post/…
murki

4
मैं अपने कंस्ट्रक्टरों के दौरान सत्र का उपयोग करना चाहता हूं ताकि मुझे पहले से संग्रहीत सत्र की जानकारी मिल सके। हां, मैं OnActionExecuting विधि को ओवरराइड कर सकता हूं, लेकिन यह निश्चित रूप से एक सुरुचिपूर्ण समाधान नहीं है।
क्रिस अर्नोल्ड

8

आप अपना सत्र सेट करने के लिए प्रारंभिक विधि को ओवरराइड कर सकते हैं।

protected override void Initialize(RequestContext requestContext)

2

यदि आप एक IoC कंटेनर का उपयोग कर रहे हैं, HttpSessionStateBaseतो Sessionऑब्जेक्ट के बजाय इंजेक्शन लगाने और उपयोग करने का प्रयास करें :

private static Container defaultContainer()
{
    return new Container(ioc =>
    {
        // session manager setup
        ioc.For<HttpSessionStateBase>()
           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); 
    });
}

2

यह उत्तर कुछ लोगों के लिए उपयोगी हो सकता है

अगर हम इनिशियलाइज़ मेथड को ओवरराइड करते हैं तो हमें बेस क्लास को रिक्वेस्ट कॉन्टेक्स्ट के साथ इनिशियलाइज़ करना होगा: base.Initialize (requestContext);

protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);
           

        }

उपयोगी। ध्यान दें कि विधि हस्ताक्षर protected override void Initialize(System.Web.Routing.RequestContext requestContext)
मार्टिन_ डब्ल्यूडब्ल्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.