2012-02-08 16 views
5

नहीं मिल रहा है मैं एमवीसी 3 के लिए प्लगइन सिस्टम के रूप में अलग-अलग वर्ग पुस्तकालयों में संकलित रेजर दृश्यों का उपयोग कर रहा हूं।एमवीसी 3 - संकलित रेजर व्यू _ViewStart

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

क्योंकि मैं रनटाइम पर असेंबली लोड कर रहा हूं, इसलिए मैं बोक लाइब्रेरी में वर्चुअलपाथप्रोवाइडर व्यूइंजिन का उपयोग नहीं कर रहा हूं, और इसके बजाय RazorViewEngine के आधार पर अपना स्वयं का व्यूइंजिन लागू कर चुका हूं। यह उपयुक्त नामस्थान डालने के लिए CreateView में viewPath को फिर से लिखकर काम करता है ताकि दृश्य को हल किया जा सके।

अब तक इतना अच्छा है ... मेरे पास अलग-अलग मॉड्यूल लोड हो सकते हैं, और यदि वे समान नाम साझा करते हैं तो उनके नियंत्रक टकरा नहीं जाएंगे।

मेरे पास अब एकमात्र समस्या यह है कि संकलित विचारों के लिए, _ViewStart नहीं कहा जाता है। _ViewStart मेजबान MVC3 प्रोजेक्ट में दृश्यों के लिए काम करता है, लेकिन प्लगइन असेंबली से लोड किए गए किसी भी विचार के लिए यह नहीं मिला है।

मैं इस तरह एक मार्ग सेटअप: -

RouteTable.Routes.MapRoute(
    string.Format("Plugin{0}Route", pluginName), 
    string.Format(@"Plugin/{0}/{{controller}}/{{action}}", pluginName), 
    new { }, 
    new string[] { string.Format("{0}.Controllers", pluginName) }); 

ViewEngine इस तरह दिखता है: -

public class PluginRazorViewEngine : RazorViewEngine 
{ 
    public PluginRazorViewEngine() : base() 
    { 
     ViewLocationFormats = new[] 
     { 
      "~/Plugin/%1/Views/{1}/{0}.cshtml", 
      "~/Plugin/%1/Views/{1}/{0}.vbhtml", 
      "~/Plugin/%1/Views/Shared/{0}.cshtml", 
      "~/Plugin/%1/Views/Shared/{0}.vbhtml", 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/{1}/{0}.vbhtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/{0}.vbhtml" 
     }; 

(% 1 विधानसभा के नाम के साथ प्रतिस्थापित किया गया है)

और असेंबली बीओसी लाइब्रेरी के साथ पंजीकृत है: -

BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, string.Format("/Plugin/{0}/", pluginName)); 

जब दृश्य प्लगइन असेंबली से लोड किया जाता है (इस उदाहरण में "खाते"), दृश्य ठीक और प्रदर्शित होता है। लेकिन तब यह _ViewStart के लिए इन स्थानों में लग रहा है: -

~/plugin/accounts/views/invoice/_viewstart.cshtml 
~/plugin/accounts/views/invoice/_viewstart.vbhtml 
~/plugin/accounts/views/_viewstart.cshtml 
~/plugin/accounts/views/_viewstart.vbhtml 
~/plugin/accounts/_viewstart.cshtml 
~/plugin/accounts/_viewstart.vbhtml 
~/plugin/_viewstart.cshtml 
~/plugin/_viewstart.vbhtml 
~/_viewstart.cshtml 
~/_viewstart.vbhtml 

लेकिन यह ~/दृश्य/साझा/_ViewStart.cshtml जहां फ़ाइल जीवन में नहीं लगती है।

मैं अपने ViewEngine (AreaMasterLocationFormats, AreaPartialViewLocationFormats, AreaViewLocationFormats, MasterLocationFormats, PartialViewLocationFormats और ViewLocationFormats) के सभी स्थान स्वरूपों को बदलने लेकिन उनमें से कोई एक फर्क करने लगते हैं की कोशिश की है।

मैंने चारों ओर देखा है और ऐसा लगता है कि System.Web.WebPages.StartPage.GetStartPage एक दृश्य में प्रारंभ पृष्ठ खोजने और वापस करने के लिए ज़िम्मेदार है, लेकिन मुझे यह देखने के लिए कोई जानकारी नहीं मिल रही है कि यह कहां दिखता है।

मैं ~/_ViewStart.cshtml (स्थानों यह लग रहा है में से एक) को _ViewStart.cshtml चलती की कोशिश की है लेकिन मैं तुरंत मिलता है: -

Unable to cast object of type 'ASP._Page__ViewStart_cshtml' to type 'System.Web.WebPages.StartPage'. 

मैं क्या पढ़ा है के अनुसार कौन सा है, क्योंकि _ViewStart को नीचे/दृश्य

क्या मैं संशोधित कर सकता हूं जहां एमवीसी _ViewStart की तलाश में है?

BoC पुस्तकालय यह खुद IVIEW है लागू करता है, और कहता है निम्नलिखित: -

startPage = this.StartPageLookup(page, VirtualPathFactoryManagerViewEngine.ViewStartFileName, this.ViewStartFileExtensions); 

लेकिन इस मामले में ViewStartFileName बस है "_ViewStart" और ViewStartFileExtensions सिर्फ cshtml और vbhtml रहे हैं ... कुछ भी नहीं है कि जहां नियंत्रण होगा एमवीसी फाइल के लिए खोजना चाहिए।

उत्तर

1

एक विचार ... (के रूप में, यह प्रयास नहीं किया है यह काम करेगा नहीं विचार है।?)

शायद RazorView से इनहेरिट (या यह पूरी तरह से जगह, पर विचार पर एक नजर है - हम आपको के रूप में फिर मिलेंगे आप एक विधि को फिर से लिख रहे होंगे जो कक्षा का बड़ा हिस्सा है)।

RazorView जहां StartPage.GetStartPage एक StartPageLookup संपत्ति को यह बताए के माध्यम से पेश किया जाता है:

// In RazorView constructor: 
StartPageLookup = StartPage.GetStartPage; 

दुर्भाग्य से, कि प्रतिनिधि संपत्ति, आंतरिक है, तो आप बस अपने व्युत्पन्न वर्ग 'निर्माता में इसे अधिलेखित नहीं कर सकते। हालांकि, आप (, MVC3 स्रोत कोड लाइनों के बहुत से हटाया, लाइन टूट जाता है मेरे द्वारा जोड़ा) RazorView.RenderView ओवरराइड करने के लिए है, जो है, जहां यह प्रयोग किया जाता है सक्षम हो सकते हैं:

protected override void RenderView(ViewContext viewContext, TextWriter writer, 
    object instance) 
{ 
    // [SNIP] 

    WebPageRenderingBase startPage = null; 
    if (RunViewStartPages) { 
    // HERE IT IS: 
    startPage = StartPageLookup(
     webViewPage, 
     RazorViewEngine.ViewStartFileName, 
     ViewStartFileExtensions 
    ); 
    } 
    webViewPage.ExecutePageHierarchy(
    new WebPageContext(
     context: viewContext.HttpContext, 
     page: null, 
     model: null), 
    writer, startPage); 
} 

बदलें कि अपनी खुद की साथ StartPageLookup कॉल लुकअप, फिर CreateView और CreatePartialView के परिणाम को अपने PluginRazorViewEngine में अपने नए PluginRazorView कक्षा के साथ बदलें।

+0

जैसा आपने सुझाव दिया था और RazorView से विरासत में अपना "प्लगइनरज़रव्यू" बनाया है। मुझे आपके द्वारा सुझाए गए रेंडरव्यू को ओवरराइड करना पड़ा और मैंने एमवीसी गेटस्टार्ट पेज विधि को दोहराने की कोशिश की और अतिरिक्त पथ खोजने के लिए बस अपना खुद का तर्क जोड़ें, हालांकि यह आंतरिक और प्रतिबिंब का एक खनन क्षेत्र है इसलिए मैंने अभी कुछ एक साथ हैक किया है साबित करें कि यह काम करता है और मुझे इसे बाद में साफ करना होगा। यह दिलचस्प है कि उन्होंने यहां एक प्रतिनिधि का उपयोग किया है ... ऐसा लगता है कि विभिन्न खोज विधियों का उपयोग किया जा सकता है, लेकिन उन्हें निर्दिष्ट करने का कोई तरीका नहीं है। सहायता के लिए बहुत धन्यवाद। – Aleks

+0

हाँ, यही मैंने सोचा था। जैसा कि आप कहते हैं, वे लुकअप विधि को बदलने की अनुमति देने के लिए एक प्रतिनिधि का उपयोग कर रहे हैं, लेकिन फिर इसे 'आंतरिक' घोषित करें, इसलिए यह केवल एमवीसी नेमस्पेस है जो वास्तव में इसे बदल सकता है ... – JimmiTh

1

तो, मेरे अपने सवाल का जवाब देने ... यह कोई की तरह लगता है, तो आप संशोधित नहीं कर सकते जहां MVC _ViewStart के लिए लग रहा है ...

System.Web.WebPages.StartPage के स्रोत को देखते हुए। GetStartPage (जो मुझे here से मिला है) मैं देख सकता हूं कि यह केवल रूट तक कॉलिंग पेज से पथ को पार करता है, और इस व्यवहार को नियंत्रित करने का कोई तरीका नहीं प्रतीत होता है (यानी यह हार्ड-कोडित है System.Web.WebPages.StartPage)

सामान्य परिस्थितियों (यानी एक मानक एमवीसी 3 लेआउट) के तहत यह ठीक रहेगा ... सभी विचार नीचे/दृश्य बैठते हैं और इसी तरह मुख्य _ViewStart फ़ाइल भी होती है, जिसे GetStartPage तक पहुंचने पर मूल्यांकन किया जाएगा यह।

तो मैंने मूल रूप से जो किया है वह मेरे विचारों को/दृश्य फ़ोल्डर पदानुक्रम से बाहर ले जाकर इस कार्यक्षमता को तोड़ देता है।

मुझे लगता है कि इसका मतलब है कि मैं या तो अपनी _ViewStart फ़ाइल को उस स्थान पर ले जा सकता हूं जहां यह मिलेगा (मेरे सभी प्लगइन के लिए एक सामान्य _ViewStart होने का मेरा इच्छित लक्ष्य किस प्रकार टूटता है) या फिर से लिखने का कोई तरीका/दृश्य/साझा/साझा/_ViewStart (जो मुझे तुरंत स्पष्ट नहीं है) में सही फ़ाइल में उस पदानुक्रम में _ViewStart के अनुरोधों पर पुनः निर्देशन।

दिलचस्प बात यह है कि MVC3 कोड, /, जो मैं क्या पढ़ा है के आधार पर काम नहीं करेगा में _ViewStart के लिए दिखेगा "प्रकार की वस्तु कास्ट करने में असमर्थ है, जिसके परिणामस्वरूप है 'एएसपी। पृष्ठ _ViewStart_cshtml' के लिए टाइप करें 'System.Web.WebPages.StartPage' "त्रुटि (हालांकि मुझे संदेह है कि यह सिर्फ इसलिए है क्योंकि डिफ़ॉल्ट /web.config में फ़ाइल को सही तरीके से पार्स करने के लिए आवश्यक सामग्री नहीं है, जबकि /Views/web.config करता है)

संबंधित मुद्दे