2013-02-15 36 views
12

मुझे अपने Asp.Net MVC 4 प्रोजेक्ट में 404 प्रतिक्रियाओं को हल करने में समस्या हो रही है। यह VS2012 लक्ष्यीकरण 4.5 में बनाया गया है।404 बाहरी असेंबली में नियंत्रकों पर

मेरे पास स्टैंड-अलोन डीएलएल में निर्मित पूर्व-संकलित विचार और नियंत्रक हैं। मैं डीएलएल को गतिशील रूप से लोड करने और उन्हें अपने मूल प्रोजेक्ट से निरीक्षण करने में सक्षम हूं, यहां तक ​​कि उन पर विधियों का आह्वान भी करता हूं; हालांकि, ऐसा लगता है कि एमवीसी फ्रेमवर्क नियंत्रकों से अवगत नहीं है। मैं यहाँ करीब हूँ, लेकिन कुछ याद आ रही है। नियंत्रकों और दृश्य

नियंत्रकों पर

पृष्ठभूमि एक स्टैंड-अलोन MVC परियोजना में बनाया गया और Controller से विरासत कर रहे हैं। वहां कुछ भी दिलचस्प नहीं है। विचार RazorGenerator का उपयोग करते हैं और प्रोजेक्ट में रहने वाले वर्ग बन जाते हैं।

प्रोजेक्ट का आउटपुट एक डीएलएल है जिसमें सही ढंग से नियंत्रक और विचार होते हैं।

डीएलएल एक विशिष्ट इंटरफ़ेस को लागू करते हैं, हम लाइब्रेरी में एक अलग वर्ग (नियंत्रक का हिस्सा नहीं) में IPlugin कहेंगे।

DLLs

लोड हो रहा है दृश्य स्टूडियो में व्यवस्थापक के रूप में चल रहा है मैं अपने ऐप है, जो आईआईएस के तहत होस्ट किया गया है संकलन। प्रोजेक्ट के निर्माण के साथ, मैंने अपनी "प्लगइन्स" निर्देशिका में एक प्लगइन डीएलएल ड्रॉप किया। डिबगिंग के बिना (यह बाद में महत्वपूर्ण हो जाता है), मैं आईई खोलता हूं और साइट पर नेविगेट करता हूं। ध्यान दें कि इस बिंदु पर ऐप बनाया गया है, लेकिन कभी नहीं चलता है, इसलिए स्टार्टअप ईवेंट आग लगेंगे। यदि मैं ऐप पूल रीसायकल करता हूं तो यहां सबकुछ अभी भी सुसंगत है।

मैं दो तरीकों, PreStart और PostStart के साथ एक Startup वर्ग है और क्रमश: WebActivator.PreApplicationStartMethod और WebActivator.PostApplicationStartMethod का उपयोग कर विधियां प्रारंभ।

PreStart जहाँ मैं निम्न कार्य है:

  • करने के लिए AppDomain.CurrentDomain.DynamicDirectory
  • लोड प्रकार मेरी "प्लग इन" निर्देशिका
  • कॉपी सभी प्लग-इन में सभी प्लगइन DLLs की एक सूची प्राप्त ... अगर इसमें एक IPlugin मैं तो
    • विधानसभा BuildManager
    • कॉल करने के लिए तरीकों के कुछ वर्ग है कि छोटा सा भूत पर जोड़े lements IPlugin

'PostStart' मैं कोड के इस थोड़ा प्रयास करना चाहिए (RazorGenerator.Mvc से कोड के आधार पर):

foreach (var assembly in Modules.Select(m=>m.Value)) 
{ 
    var engine = new PrecompiledMvcEngine(assembly) 
    { 
     UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal 
    }; 

    ViewEngines.Engines.Insert(0, engine); 
    VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); 
} 

Modules इस संदर्भ में एक मुख्य/मान जोड़े है, जहां मूल्य भारित असेंबली हैं। इस कोड का उद्देश्य यह सुनिश्चित करना है कि एमवीसी प्रत्येक असेंबली के लिए एक व्यू इंजन जोड़कर विचारों से अवगत है जो विचारों को हल करने के बारे में जानता है (यह रेजर जेनरेटर का हिस्सा है)।

मुझे कैसे पता मैं बंद (लेकिन स्पष्ट रूप से सिगार अभाव)

IPlugin एक विधि RegisterRoutes कहा जाता है जहां, आप अनुमान लगाया यह, मार्गों जो लोग इंटरफ़ेस को लागू करने के लिए पंजीकृत होने के लिए कर रहे हैं परिभाषित करता हूँ। मैं इस विधि को PreStart में कॉल करता हूं और मार्ग जोड़े जाते हैं - मैंने सत्यापित किया है कि ये मेरी रूट तालिका में मौजूद हैं। उदाहरण के लिए, एक मार्ग PreStart के दौरान मेरे प्लगइन, विधि के गतिशील मंगलाचरण के माध्यम से बनाया में परिभाषित पर, मैं एक DataToken के रूप में कुछ इस तरह जब मेरे मार्गों की जांच देखें:

Namespaces = Plugin.Name.Controllers 

तो, मार्ग में पंजीकृत है, असेंबली लोड हो गई है, मैंने सत्यापित किया है कि डीएलएल को ऐपडोमेन की डायनामिक डायरेक्टरी में सही ढंग से कॉपी किया गया है। मैं उन कक्षाओं के सदस्यों को आमंत्रित करने में सक्षम हूं जो रनटाइम पर गतिशील रूप से लोड होते हैं। लेकिन जब मैं मार्ग से मेल खाने वाले यूआरएल पर नेविगेट करता हूं तो मुझे 404 मिलता है। यह एक "दृश्य का पता नहीं लगा सका" YSOD है, यह नियंत्रक को बिल्कुल नहीं ढूंढने के समान है।

यहां वह हिस्सा है जो मुझे से बिल्ली को भ्रमित करता है: यदि इस बिंदु पर, कुछ भी किए बिना, मैं विजुअल स्टूडियो पर वापस आ जाता हूं और F5 दबाता हूं ... सबकुछ काम करता है।

ऐसा लगता है कि विजुअल स्टूडियो नियंत्रक के बारे में जागरूक हो रहा है जिस तरह से मैं पहचान नहीं सकता, और एमवीसी फ्रेमवर्क इस पर उठा रहा है।

अंत में, प्रश्न

मैं क्या याद आ रही है, और कैसे मैं MVC फ्रेमवर्क मेरी नियंत्रक के बारे में पता होना करने के लिए मिलता है?

और हे, इस बिंदु पर, यदि आप अभी भी इसे पढ़ रहे हैं, धन्यवाद। :)

+0

1. क्या वीएस कैसिनी का उपयोग कर चल रहा है? इसे आईआईएस एक्सप्रेस में बदलने का प्रयास करें और जांचें कि क्या यह सही तरीके से काम करता है या नहीं। 2. स्थापित करने का प्रयास करें [रूटडेबगर] (http://nuget.org/packages/routedebugger) - शायद यह आपको कुछ संकेत दे सकता है कि क्या IIS – Pranav

+0

धन्यवाद @Pranav के तहत मार्ग सही तरीके से पंजीकृत किए जा रहे हैं, लेकिन यह पहले से ही आईआईएस पर है। मार्ग डीबगर से पता चलता है कि मार्ग काम कर रहे हैं। – MisterJames

+1

क्या यह एक मुद्दा हो सकता है? http://stackoverflow.com/questions/14971895/using-precompiledmvcengine-findview-throws-invalidoperationex-f-looks-f – Tengiz

उत्तर

5

यह पता चला है कि यह Asp.Net में एक बग है।

एएसपी के ईलॉन लिपटन के साथ इस मुद्दे पर चर्चा करने के बाद।नेट टीम, और सोच रहा था कि एमवीसी फ्रेमवर्क, एइलॉन और कुछ टीम के सदस्यों ने कुछ चीजों में खोला था और पाया कि त्रुटि इस वार्तालाप के निचले स्तर पर थी: http://aspnetwebstack.codeplex.com/discussions/403529

उन्होंने एक कामकाज भी सुझाया जिसमें एक और शामिल था BuildManager पर कॉल AddReferencedAssembly करने के लिए कॉल, जो मैं निम्नलिखित कोड के माध्यम से कार्यान्वित करने के बाद:

// Add the plugin as a reference to the application 
    BuildManager.AddReferencedAssembly(assembly); 
    BuildManager.AddCompilationDependency(assembly.FullName); 

यह आपको अपने आवेदन-पूर्व init चरण में स्टार्टअप पर अतिरिक्त नियंत्रकों/संकलित दृश्य जोड़ने के लिए अनुमति देता है। अब मैं अपनी प्लगइन्स निर्देशिका में डीएलएल की सूची के माध्यम से लूपिंग कर रहा हूं और उन्हें ऊपर के रूप में BuildManager पर धक्का दे रहा हूं।

यहां एकमात्र सीमा यह है कि आप असेंबली को हटा सकते हैं या गतिशील रूप से कैश साफ़ कर सकते हैं। ऐसा करने का एकमात्र तरीका यह है कि मैंने संदर्भित असेंबली और संकलन निर्भरताओं को पहले अज्ञात असेंबली जोड़ना है। मैं पूर्व-अनुप्रयोग प्रारंभिकरण के दौरान एक नई असेंबली को गतिशील रूप से उत्सर्जित करने के साथ प्रयोग कर रहा हूं ताकि मैं हमेशा कैश को साफ़ कर सकूं और कैश साफ़ कर सकूं और एक नई असेंबली को उठाकर पहले शामिल प्लगइन को हटा सकूं।

उम्मीद है कि यह किसी और को वहां मदद करता है।

चीयर्स।

+0

आपके विस्तृत प्रश्न और उत्तर के लिए बहुत बहुत धन्यवाद। एक चीज जो मुझे नहीं मिलती है, आप कस्टम कंट्रोलर फैक्ट्री का उपयोग क्यों नहीं कर रहे हैं (देखें 'नियंत्रकबिल्डर.कुरेंट.सेट कंट्रोलर फैक्टरी')? यह आपको कौन सा नियंत्रक उत्पन्न करने के लिए पूर्ण नियंत्रण रखने की अनुमति देगा, है ना? – Dejan

1

यह इस मुद्दे की तरह दिखता है:

MVC अलग दृष्टिकोण इंजन से को स्पष्ट दृश्य कैश प्रविष्टियों को देखने के इंजन की विधानसभा से योग्य प्रकार का नाम उपयोग करता है। तो यह एक से अधिक प्रीकंपिल्टेड एमवीसीइंजिन ऑब्जेक्ट ( के रूप में संभव नहीं है जब आपके पास एक से अधिक असेंबली में प्रीकंपिल्ड दृश्य हैं)। समस्या को प्रत्येक असेंबली के लिए प्रीकंपिल्टेड एमवीसीइंजिन से एक अलग व्युत्पन्न कक्षा बनाकर हल किया जा सकता है। या असेंबली से कुछ प्रकार के साथ पैरामीटरकृत एक जेनेरिक व्युत्पन्न वर्ग बनाकर।

आलेख here है।

+0

धन्यवाद नेनाद, लेकिन इस समय मैं केवल एक प्लगइन चला रहा हूं, इसलिए लोड करने का प्रयास करने वाला केवल एक ही है। इसमें कारक हो सकता है, लेकिन मेरे पास एक बार में 2 प्लगइन्स चल रहे हैं, इसलिए मुझे यकीन नहीं है कि यह होगा। साथ ही, यह उस समस्या का समाधान नहीं करता है जिसमें मेरा नियंत्रण है, नियंत्रक स्थित नहीं है। यह बक्षीस की कुंजी है। चीयर्स। – MisterJames

+0

क्या आप त्रुटि पर अधिक जानकारी दे सकते हैं? स्टैक ट्रेस? – Nenad

+0

मेरी इच्छा है कि वहां थे। जब मैं एक दृश्य तक पहुंचने का प्रयास करता हूं तो मुझे बस नियंत्रक पर 404 मिल रहा है। मेरे पास Log4Net और ELMAH जा रहा है और कुछ भी गलत नहीं है कि मैं उठा रहा हूं (हर चरण में लॉगिंग के साथ)। मेरे पास इस बारे में अधिक जानकारी है कि मैं इस सप्ताह Asp.Net टीम के कुछ सदस्यों के साथ कुछ चीजों के माध्यम से बात करने के बाद प्रश्न में शामिल करूंगा। – MisterJames

0

@MisterJames, इस पर एक नज़र डालें:

Asp.Net Mvc Pluggable Application

मुझे आशा है कि यह उपयोगी है।

+0

फ़ेलिप, यह एक ही समाधान के भीतर से परियोजना में क्षेत्रों का उपयोग कर रहा है और यह एक पूरी तरह से अलग दृष्टिकोण है। मेरी जरूरतों को प्लगइन के लिए स्टैंडअलोन समाधान होना है। मैं यह देखने के लिए इसे और अधिक विस्तार से बताऊंगा कि क्या कोई संकेत है, लेकिन जैसा कि यह खड़ा है, मुझे विश्वास नहीं है कि यह मेरे परिदृश्य में मदद करेगा। – MisterJames