मुझे ASP.NET MVC 1 में HttpContextBase से HttpContext ऑब्जेक्ट कैसे मिलता है?


155

मैं कुछ WebForms / MVC-agnostic टूल के साथ काम कर रहा हूं, और मुझे HttpContextकिसी HttpContextBaseऑब्जेक्ट के संदर्भ में एक उदाहरण प्राप्त करने की आवश्यकता है । मैं उपयोग नहीं कर सकता HttpContext.Currentक्योंकि मुझे इसके साथ ही अतुल्यकालिक रूप से काम करने की आवश्यकता है ( एक अतुल्यकालिक अनुरोध के दौरान HttpContext.Currentरिटर्न null)। मुझे पता है HttpContextWrapper, लेकिन गलत तरीके से चला जाता है।

जवाबों:


250

सबसे सरल तरीका है आवेदन प्राप्त करना ApplicationInstance, और अपनी Contextसंपत्ति का उपयोग करना :

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;

( इश्माएल स्मरनॉव के लिए धन्यवाद जिन्होंने टिप्पणियों में यह नोट किया)

मूल उत्तर:

आप कर सकते हैं, खासकर अगर HttpContextBaseआपके द्वारा दिया गया उदाहरण HttpContextWrapperरन-टाइम पर टाइप का हो। निम्न उदाहरण दिखाता है कि आप यह कैसे कर सकते हैं। यह Fooमान लेता है कि आपके पास एक ऐसी विधि है जिसे संदर्भ कहा जाता है, HttpContextBaseलेकिन फिर तीसरे पक्ष की विधानसभा में एक विधि को कॉल करने की आवश्यकता है (जिसे आपको संशोधित करने का सौभाग्य नहीं मिल सकता है) जो संदर्भ के रूप में टाइप होने की उम्मीद कर रहा है HttpContext

void Foo(HttpContextBase context) 
{
    var app = (HttpApplication) context.GetService(typeof(HttpApplication));
    ThirdParty.Bar.Baz(app.Context);
}

// Somewhere in assembly and namespace ThirdParty,
// in a class called Bar, there is Baz expecting HttpContext:

static void Baz(HttpContext context) { /* ... */ }

HttpContextBaseGetServiceसमर्थन के परिणामस्वरूप एक विधि कहलाती है IServiceProvider। लिपटे उदाहरण के कार्यान्वयन के लिए प्रतिनिधियों का GetServiceओवरराइड । के कार्यान्वयन की तरह सामान्य संदिग्धों के लिए क्वेरी करने की अनुमति देता , , और इतने पर। यह सिर्फ इतना होता है कि एक संपत्ति होती है जिसे कॉनटेक्स्ट कहा जाता है और जो इसका एक उदाहरण देता है । तो एक लिपटे पर हो जाता है पूछकर उदाहरण के लिए के माध्यम से पढ़ने के बाद लौट आए की संपत्ति उदाहरण।HttpContextWrapperGetServiceHttpContextGetServiceHttpContextHttpApplicationHttpRequestHttpResponseHttpApplicationHttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication

विपरीत HttpContextBase, GetServiceकी एक सार्वजनिक सदस्य के रूप में प्रकट नहीं होता है HttpContext, लेकिन है कि क्योंकि है HttpContextऔजार IServiceProvider.GetServiceस्पष्ट रूप से, जबकि HttpContextBaseऐसा नहीं करता।

ध्यान रखें कि Fooअब परीक्षण योग्य नहीं है क्योंकि यह HttpContextपरीक्षण के दौरान अंतर्निहित को उजागर करने में सक्षम होने पर निर्भर करता है और जो पहले स्थान पर नकली / ठूंठ के लिए असंभव है। इस जवाब की बात है, तथापि, प्रश्नों के उत्तरों, "मैं HttpContextBase से एक HttpContext वस्तु कैसे मिलता है?" है, सचमुच । सचित्र तकनीक उन स्थितियों में उपयोगी होती है, जहां आप अपने आप को उन घटकों के बीच पाले हुए होते हैं, जिन्हें आपको संशोधित करने की आवश्यकता नहीं होती है।


3
बहुत दिलचस्प जवाब, बस इसे MVC में स्वयं उपयोग किया गया लॉगिंग के लिए एक त्रुटि फ़िल्टर से ELMAH तक HttpContext पास करने के लिए।
क्रिस मैरिसिक

1
अच्छा जवाब, शर्त है कि खुदाई का एक सा लिया? :)
लॉन्गहेड्डीसी

बहुत बढ़िया जवाब! मैंने विशेष रूप से अपने
एल्माह में

36
HttpContextBase के साथ, क्या आप फोन नहीं कर सकते context.ApplicationInstance.Context?
इस्माइल स्मरनवॉक्ट

@IshmaelSmyrnow हिम्मत नहीं है, मैं कैसे याद किया कि सभी Http*Baseरूपों के बीच में लौट आए HttpContextBase। : P मैं उत्तर को अपडेट करूंगा।
आतिफ अजीज

32

आप ऐसा कर सकते हैं,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);

16
-1 यह गलत तरीका है, यह आपको तब देता है जब आपके पास कॉन्सेप्ट होता है, न कि दूसरे तरीके से।
क्रिस मैरिसिक

14

आप नहीं कर सकते।

इसका पूरा उद्देश्य HttpContextBaseठोस HttpContextवर्ग पर निर्भरता को समाप्त करना है । यह जबकि हो सकता है एक ठोस होते हैं HttpContext (के साथ मामला है जैसे httpContextWrapper) , अन्य कार्यान्वयन बिल्कुल कुछ भी नहीं के साथ क्या करना पड़ सकता है HttpContext

आपका सबसे अच्छा विकल्प एक कस्टम सार फैक्ट्री को परिभाषित करना है जो HttpContextBaseआपके लिए मिल सकता है , क्योंकि आप हमेशा एक HttpContextमें एक ठोस लपेट सकते हैं HttpContextWrapper


13
यह, वैसे, बुरी तरह से किया गया था - मैं समझता हूं कि यूनिट परीक्षणों के लिए एक सेटअप होना चाहते हैं, और मुझे अमूर्तता की परतें समझ में आती हैं - लेकिन WTH क्या आप तब करना चाहते हैं जब आप मौजूदा ASP.NET वर्गों का उपयोग करना चाहते हैं जो एक HttpChtetext की उम्मीद करते हैं? (जैसे msdn.microsoft.com/en-us/library/… )
1

हां, IHttpHandlerआप अपने यूनिट परीक्षणों के लिए (रिस्पॉन्स रैपर) में एक संख्या में सार डाल सकते हैं, जो कि आपके द्वारा लागू किए गए परीक्षणों का परीक्षण करने के लिए समाप्त होता है, जो सही नहीं लगता है, लेकिन एकमात्र विकल्प होता है।
क्रिस एस।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.