36

मैं कस्टम VirtualFile और VirtualPathProvider कार्यान्वयन कि सफलतापूर्वक एम्बेडेड संसाधन है कि कर रहे हैं आंशिक दृश्य प्राप्त कर रहे हैं लिखा कस्टम VirtualPathProvider का उपयोग करना।लोड करने के लिए एम्बेडेड संसाधन आंशिक दृश्य

हालांकि, जब मैं उन्हें रेंडर करने का प्रयास यह इस त्रुटि पैदा करता है:

Html.RenderPartial("~/Succeed.Web/Succeed.Web.Controls.SImporter._SImporter.cshtml"); 
:

The view at '~/Succeed.Web/Succeed.Web.Controls.SImporter._SImporter.cshtml' must derive from WebViewPage, or WebViewPage<TModel>.

जब आंशिक दृश्य प्रतिपादन, एक नियमित रूप से देखें के अंदर, तो वह ऐसा लग रहा है

यह मानने के कारण क्या यह आंशिक दृश्य नहीं है?

संपादित करें: मैंने वर्चुअल फ़ाइल & वर्चुअल फ़ाइल प्रदाता कार्यान्वयन दोनों के लिए अपना कोड पोस्ट किया है जो इस घटक को काम करने के लिए समाधान की तलाश में ठोकर खाती है। यह प्रश्न प्रश्न शीर्षक के आधार पर उन लोगों के लिए भी अच्छी तरह से सेवा करेगा।

पहले संदर्भ के लिए VirtualFile दिया गया है:

public class SVirtualFile : VirtualFile 
{ 
    private string m_path; 

    public SVirtualFile(string virtualPath) 
     : base(virtualPath) 
    { 
     m_path = VirtualPathUtility.ToAppRelative(virtualPath); 
    } 

    public override System.IO.Stream Open() 
    { 
     var parts = m_path.Split('/'); 
     var assemblyName = parts[1]; 
     var resourceName = parts[2]; 

     assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName); 
     var assembly = System.Reflection.Assembly.LoadFile(assemblyName + ".dll"); 

     if (assembly != null) 
     { 
      return assembly.GetManifestResourceStream(resourceName); 
     } 
     return null; 
    } 
} 

VirtualPathProvider:

public class SVirtualPathProvider : VirtualPathProvider 
{ 
    public SVirtualPathProvider() 
    { 

    } 

    private bool IsEmbeddedResourcePath(string virtualPath) 
    { 
     var checkPath = VirtualPathUtility.ToAppRelative(virtualPath); 
     return checkPath.StartsWith("~/Succeed.Web/", StringComparison.InvariantCultureIgnoreCase); 
    } 

    public override bool FileExists(string virtualPath) 
    { 
     return IsEmbeddedResourcePath(virtualPath) || base.FileExists(virtualPath); 
    } 

    public override VirtualFile GetFile(string virtualPath) 
    { 
     if (IsEmbeddedResourcePath(virtualPath)) 
     { 
      return new SVirtualFile(virtualPath); 
     } 
     else 
     { 
      return base.GetFile(virtualPath); 
     } 
    } 

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) 
    { 
     if (IsEmbeddedResourcePath(virtualPath)) 
     { 
      return null; 
     } 
     else 
     { 
      return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); 
     } 
    } 
} 

और बेशक, भूल नहीं है अपनी परियोजना के Global.asax फ़ाइल में इस नए प्रदाता रजिस्टर करने के लिए Application_Start() ईवेंट

System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new SVirtualPathProvider()); 

उत्तर

44

क्योंकि अब आप servi हैं किसी अज्ञात स्थान से अपने विचारों एनजी वहाँ अब लागू नहीं होता और अपना रेजर दृश्य (<pages pageBaseType="System.Web.Mvc.WebViewPage">) के लिए आधार वर्ग को इंगित करता है जो ~/Views/web.config फ़ाइल है। इसलिए आप बेस क्लास को इंगित करने के लिए प्रत्येक एम्बेडेड व्यू के शीर्ष पर @inherits निर्देश जोड़ सकते हैं।

@inherits System.Web.Mvc.WebViewPage 
@model ... 
+0

आपको बहुत बहुत धन्यवाद। मेरा एकमात्र अफसोस यह है कि मेरे पास देने के लिए एक वोट है। = पी ऊपर इस उत्तर को वोट दें –

+3

@ डारिन डिमिट्रोव मुझे नहीं लगता कि आप एक चाल के बारे में जानते हैं जिसे मैं इंटेलिजेंस को प्रोत्साहित करने के लिए प्रोत्साहित कर सकता हूं ताकि इसे मेरे डीएल के अंदर एक दृश्य के रूप में पेश किया जा सके? अभी, मेरे विचारों के साथ बहुत कम इंटेलिजेंस समर्थन है जो मैंने अपने डीएल –

+0

@ मैट्यूकॉक्स में रखा है, मुझे विचारों में इंटेलिजेंस के बारे में बहुत कुछ पता नहीं है। यह बहुत समय पहले हुआ था जब मैंने उस पर भरोसा करना बंद कर दिया था। यदि फ़ाइल में '.cshtml' एक्सटेंशन है तो क्या आपको Intellisense नहीं मिलता है? –

6

मैंने ओपीएस को आधार के रूप में उत्तर दिया लेकिन थोड़ा सा विस्तार किया और मेरे समाधान में प्रश्न का उत्तर शामिल किया।

यह इतने पर यहाँ कुछ हद तक एक सामान्य रूप से पूछे सवाल की तरह लगता है और इसलिए मैंने सोचा कि यह मेरे काम के समाधान साझा करने के लिए उपयोगी हो सकता है मैं एक पूरा जवाब नहीं देखा है।

मैं एक डेटाबेस से मेरी संसाधनों के लोड और मैं उन्हें डिफ़ॉल्ट कैश (System.Web.Caching.Cache) में कैश की है।

क्या मैं कुंजी है कि मैं संसाधन देखने के लिए उपयोग कर रहा हूँ पर एक कस्टम CacheDependency निर्माण कर रहा है कर समाप्त हो गया

। इस तरह, जब भी मेरा अन्य कोड उस कैश (संपादन पर, इत्यादि) को अमान्य करता है, उस कुंजी पर कैश निर्भरता हटा दी जाती है और वर्चुअलपाथप्रोवाइडर बदले में अपने कैश को अमान्य कर देता है और वर्चुअलफाइल पुनः लोड हो जाता है।

मैंने कोड भी बदल दिया ताकि यह स्वचालित रूप से विरासत कथन को प्रीपेड कर सके ताकि उसे मेरे डेटाबेस संसाधन में संग्रहीत करने की आवश्यकता न हो और मैं स्वचालित रूप से कथन का उपयोग करके कुछ डिफ़ॉल्ट रूप से प्रीपेड करता हूं क्योंकि यह "व्यू" लोड नहीं होता है सामान्य चैनल, इसलिए आपके web.config या व्यूस्टार्ट में कुछ भी डिफ़ॉल्ट शामिल नहीं है।

CustomVirtualFile:

public class CustomVirtualFile : VirtualFile 
{ 
    private readonly string virtualPath; 

    public CustomVirtualFile(string virtualPath) 
     : base(virtualPath) 
    { 
     this.virtualPath = VirtualPathUtility.ToAppRelative(virtualPath); 
    } 

    private static string LoadResource(string resourceKey) 
    { 
     // Load from your database respository or whatever here... 
     // Note that the caching is disabled for this content in the virtual path 
     // provider, so you must cache this yourself in your repository. 

     // My implementation using my custom service locator that sits on top of 
     // Ninject 
     var contentRepository = FrameworkHelper.Resolve<IContentRepository>(); 

     var resource = contentRepository.GetContent(resourceKey); 

     if (String.IsNullOrWhiteSpace(resource)) 
     { 
      resource = String.Empty; 
     } 

     return resource; 
    } 

    public override Stream Open() 
    { 
     // Always in format: "~/CMS/{0}.cshtml" 
     var key = virtualPath.Replace("~/CMS/", "").Replace(".cshtml", ""); 

     var resource = LoadResource(key); 

     // this automatically appends the inherit and default using statements 
     // ... add any others here you like or append them to your resource. 
     resource = String.Format("{0}{1}", "@inherits System.Web.Mvc.WebViewPage<dynamic>\r\n" + 
              "@using System.Web.Mvc\r\n" + 
              "@using System.Web.Mvc.Html\r\n", resource); 

     return resource.ToStream(); 
    } 
} 

CustomVirtualPathProvider:

public class CustomVirtualPathProvider : VirtualPathProvider 
{ 
    private static bool IsCustomContentPath(string virtualPath) 
    { 
     var checkPath = VirtualPathUtility.ToAppRelative(virtualPath); 
     return checkPath.StartsWith("~/CMS/", StringComparison.InvariantCultureIgnoreCase); 
    } 

    public override bool FileExists(string virtualPath) 
    { 
     return IsCustomContentPath(virtualPath) || base.FileExists(virtualPath); 
    } 

    public override VirtualFile GetFile(string virtualPath) 
    { 
     return IsCustomContentPath(virtualPath) ? new CustomVirtualFile(virtualPath) : base.GetFile(virtualPath); 
    } 

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) 
    { 
     if (IsCustomContentPath(virtualPath)) 
     { 
      var key = VirtualPathUtility.ToAppRelative(virtualPath); 

      key = key.Replace("~/CMS/", "").Replace(".cshtml", ""); 

      var cacheKey = String.Format(ContentRepository.ContentCacheKeyFormat, key); 

      var dependencyKey = new String[1]; 
      dependencyKey[0] = string.Format(cacheKey); 

      return new CacheDependency(null, dependencyKey); 
     } 

     return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); 
    } 

    public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) 
    { 
     if (IsCustomContentPath(virtualPath)) 
     { 
      return virtualPath; 
     } 

     return base.GetFileHash(virtualPath, virtualPathDependencies); 
    } 
} 

आशा इस मदद करता है!

0

ओपी में सूचनाओं पर एमवीसी घटकों को साझा करने के लिए simple prototype बनाने के लिए ओपी में जानकारी के साथ-साथ डारिन डिमिट्रोव के जवाब पर भारी गिरावट आई। हालांकि वे बहुत उपयोगी थे, फिर भी मैं कुछ अतिरिक्त बाधाओं में भाग गया जो प्रोटोटाइप में संबोधित हैं जैसे @ मॉडल के साथ साझा विचारों का उपयोग करना।

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