थ्रेड या टाइमर में HttpServerUtility.MapPath विधि का उपयोग कैसे करें?


88

मैं System.Timers.Timerअपने Asp.Net एप्लिकेशन में उपयोग करता हूं और मुझे उस HttpServerUtility.MapPathविधि का उपयोग करने की आवश्यकता है जो केवल माध्यम से उपलब्ध हो HttpContext.Current.Server.MapPath। समस्या यह है कि है HttpContext.Currentहै nullजब Timer.Elapsedघटना आग।

क्या HttpServerUtility ऑब्जेक्ट का संदर्भ प्राप्त करने का एक और तरीका है? मैं इसे अपनी कक्षा के कंस्ट्रक्टर में इंजेक्ट कर सकता था। क्या ये सुरक्षित है ? मैं यह कैसे सुनिश्चित कर सकता हूं कि यह वर्तमान अनुरोध के अंत में एकत्रित कचरा नहीं होगा?

धन्यवाद!

जवाबों:


142

इसके HostingEnvironment.MapPath()बजाय इसका उपयोग करना संभव हैHttpContext.Current.Server.MapPath()

मैंने इसे अभी तक किसी थ्रेड या टाइमर इवेंट में आज़माया नहीं है।


कुछ (गैर व्यवहार्य) समाधान मैंने माना;

  • एकमात्र तरीका जिसकी मुझे परवाह HttpServerUtilityहै MapPath। इसलिए एक विकल्प के रूप में मैं इससे AppDomain.CurrentDomain.BaseDirectoryअपने रास्तों का उपयोग और निर्माण कर सकता था। लेकिन यह विफल हो जाएगा यदि आपका ऐप वर्चुअल निर्देशिकाओं (मेरा करता है) का उपयोग करता है।

  • एक और दृष्टिकोण: मुझे Globalकक्षा के लिए आवश्यक सभी पथ जोड़ें । इन रास्तों को हल करें Application_Start


1
हालांकि ध्यान दें कि ऊपर IIS के बाद के संस्करणों में काम नहीं करता है। IIS7 में आवेदन प्रारंभ को http अनुरोध के बाहर बुलाया जा सकता है। वह है, कोड उदाहरण। मुझे यकीन है कि HostingEnvironment.MapPath () अभी भी पहले की तरह काम करेगा।
रोबाबा

लेकिन HostingEnvironment.MapPath () एक त्रुटि देता है यदि आप फ़ोल्डर पथ को सीधे प्राप्त करने के लिए इसे और खाली स्ट्रिंग पास करते हैं ... HttpContext.Current.Server.MapPath (""); -> कार्य करता है HostingEnvironment.MapPath (""); -> त्रुटि उठाता है
VSP

14

मुझे नहीं पता कि क्या यह आपकी वर्चुअल डाइरेक्टरी के मुद्दे को हल करेगा, लेकिन मैं इसका उपयोग MapPath के लिए करता हूं:

public static string MapPath(string path)
{
    if (HttpContext.Current != null)
        return HttpContext.Current.Server.MapPath(path);

    return HttpRuntime.AppDomainAppPath + path.Replace("~", string.Empty).Replace('/', '\\');
}

path.Replace ("~", string.Empty) पथ होना चाहिए। Rplace ('~', '')
Slava

13

HostingEnvironment सही समाधान नहीं है क्योंकि यह मॉक करने के लिए एक बहुत ही कठिन वर्ग है (देखें कि कैसे यूनिट परीक्षण कोड है जो HostingEnvironment.MapPath का उपयोग करता है )।

जिन लोगों को परीक्षण की आवश्यकता होती है, उनके लिए एक बेहतर तरीका हो सकता है कि आप अपना खुद का पथ-मैपर इंटरफ़ेस बनाएं जैसा कि https://stackoverflow.com/a/1231962/85196 द्वारा प्रस्तावित है , इसे लागू करने के अलावा

public class ServerPathMapper : IPathMapper { 
 public string MapPath(string relativePath) { 
      return HostingEnvironment.MapPath(relativePath); 
 } 
} 

परिणाम आसानी से नकली है, आंतरिक रूप से HostingEnvironment का उपयोग करता है, और एक ही समय में ase69s की चिंता का संभावित पता भी लगा सकता है ।


इसने मुझे एक वेब एपीआई परियोजना के लिए पथ रिज़ॉल्यूशन के लिए कार्यान्वयन प्रदान करने की अनुमति दी, यह पुस्तकालय में System.Web या System.Net पर निर्भरता की आवश्यकता के बिना संदर्भित था। +1
डेविड पीटरसन

इस दृष्टिकोण के डीआई और
टेस्टिबिलिटी के

2

क्या आप टाइमर शुरू करने से पहले MapPath फ़ंक्शन को कॉल नहीं कर सकते हैं, और बस परिणाम कैश कर सकते हैं? क्या टिक इवेंट के अंदर मैपपाथ कॉल करना बिल्कुल सही है?


2

जब टाइमर बीतता है, तो कोई HTTP संदर्भ नहीं होता है। ऐसा इसलिए है क्योंकि टाइमर इवेंट किसी विशिष्ट HTTP अनुरोध से संबंधित नहीं हैं।

आपको क्या करना चाहिए HttpServerUtility.MapPath का उपयोग करें जहां HTTP संदर्भ उपलब्ध है। आप इसे अनुरोध पाइपलाइन घटनाओं में से एक (जैसे कि Page_Load) या किसी Global.asax घटना जैसे ApplicationStStart में कर सकते हैं।

MapPath परिणाम को Timer.Elapsed ईवेंट से सुलभ एक वैरिएबल पर असाइन करें, जहाँ आप एक विशिष्ट फ़ाइल का स्थान पाने के लिए Path.Combine का उपयोग कर सकते हैं।


0

मुझे लगता है कि इसका कारण उस समय के लिए अशक्त है (यदि आप इसके बारे में सोचते हैं), तो यह है कि टाइमर बीतने वाली घटना एक HTTP अनुरोध (इसलिए कोई संदर्भ नहीं है) के हिस्से के रूप में नहीं होती है। यह आपके सर्वर पर कुछ के कारण होता है।

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