2013-01-03 56 views
3

我正在嘗試從圖書館獲取一些視圖到主項目。我開始閱讀關於在這裏創建自己的VirtualPathProvider實現:Using VirtualPathProvider to load ASP.NET MVC views from DLLs在MVC4中創建自己的VirtualPathProvider?

我必須設置我的視圖= EmbbebedResource從庫中獲取資源。但現在正在拋出另一個錯誤。

在我的部分觀點的頭,我有以下幾點:

@model Contoso.ExercisesLibrary.AbsoluteArithmetic.Problem1 

和錯誤說:外部組件引發的異常。 c:\ Users \ Oscar \ AppData \ Local \ Temp \ Temporary ASP.NET Files \ root \ 4f78c765 \ 7f9a47c6 \ App_Web_contoso.exerciseslibrary.absolutearithmetic.view1.cshtml.38e14c22.y-yjyt6g.0.cs(46):error CS0103 :當前上下文中不存在名稱'model'

我不知道爲什麼編譯器會告訴我無法識別我的模型。當我處於設計模式時,我可以看到編譯器檢查是否正確。

檢查圖像

enter image description here

我在做什麼錯Ø我失去了什麼? 在此先感謝。

+0

您是否找到一些解決方案? –

+0

@SanjaMelnichuk沒有人! –

+0

我發現它,如果它的有趣我可以發佈它 –

回答

6

嘗試添加@inherits指令的Razor視圖的頂部:

@inherits System.Web.Mvc.WebViewPage 
@model Contoso.ExercisesLibrary.AbsoluteArithmetic.Problem1 

你需要,這是因爲你的觀點來自嵌入的資源,而不是從標準~/Views位置的原因。正如你知道在~/Views裏面有一個叫做web.config的文件。在這個文件裏有一個pageBaseType="System.Web.Mvc.WebViewPage"指令,指示~/Views裏的所有剃鬚刀文件應該從這個基本類型繼承。但是由於你的觀點現在來自一個未知的位置,你沒有指定它應該是System.Web.Mvc.WebViewPage。並且所有MVC特定的東西,例如模型,HTML幫助器......都在這個基類中定義。+

+0

嗨達林,我有同樣的問題DARF。不幸的是,你添加@inherits的提示並不能解決它(但對我來說很合理)。還有什麼可以解決的? – Sascha

+0

對不起,我不知道。當我需要使用其他項目中嵌入的Razor視圖時,這一直都適用於我。 –

0

在我的例子中,解決方案是讓虛擬路徑以「〜Views /」開始 - 就像任何正常的看法。

不工作:〜/虛擬/主頁/ Index.cshtml
工作:〜/查看/虛擬/主頁/ Index.cshtml

我認爲,這與在web.config躺在身邊做〜/視圖,併爲視圖定義了很多東西。也許任何人都可以提供更多信息。

希望無論如何都有幫助。

1

我遇到了這個問題「名稱模型」在當前上下文中不存在「。我所做的是將相同的「區域」文件夾結構(從我的嵌入式mvc項目)添加到我的主MVC項目(Areas/AnualReports/Views /)並複製web.config(默認web.config從視圖文件夾,而不是根目錄)到解決問題的視圖文件夾。我不確定這是否適用於您的情況。

更新: 將web.config(從視圖文件夾)添加到主MVC項目中的根「區域」文件夾也可以。

1

我有同樣的問題,因爲你這樣所有的搜索後,我得到了工作液

創建自己的WebViewPage基於抽象類(一般爲模型和非通用)

public abstract class MyOwnViewPage<TModel> : WebViewPage<TModel> { } 

public abstract class MyOwnViewPage : WebViewPage { } 

下一頁創建VirtualFile基於類或內嵌視圖的

class AssemblyResourceFile : VirtualFile 
    { 
     private readonly IDictionary<string, Assembly> _nameAssemblyCache; 
     private readonly string _assemblyPath; 
     private readonly string _webViewPageClassName; 
     public string LayoutPath { get; set; } 
     public string ViewStartPath { get; set; } 

     public AssemblyResourceFile(IDictionary<string, Assembly> nameAssemblyCache, string virtualPath) : 
      base(virtualPath) 
     { 
      _nameAssemblyCache = nameAssemblyCache; 
      _assemblyPath = VirtualPathUtility.ToAppRelative(virtualPath); 
      LayoutPath = "~/Views/Shared/_Layout.cshtml"; 
      ViewStartPath = "~/Views/_ViewStart.cshtml"; 
      _webViewPageClassName = typeofMyOwnViewPage).ToString(); 
     } 

     // Please change Open method for your scenario 
     public override Stream Open() 
     { 
      string[] parts = _assemblyPath.Split(new[] { '/' }, 4);  

      string assemblyName = parts[2]; 
      string resourceName = parts[3].Replace('/', '.'); 

      Assembly assembly; 

      lock (_nameAssemblyCache) 
      { 
       if (!_nameAssemblyCache.TryGetValue(assemblyName, out assembly)) 
       { 
        var assemblyPath = Path.Combine(HttpRuntime.BinDirectory, assemblyName); 
        assembly = Assembly.LoadFrom(assemblyPath); 

        _nameAssemblyCache[assemblyName] = assembly; 
       } 
      } 

      Stream resourceStream = null; 

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

       if (resourceName.EndsWith(".cshtml")) 
       { 
        //the trick is here. We must correct our embedded view 
        resourceStream = CorrectView(resourceName, resourceStream); 
       } 
      } 

      return resourceStream; 
     } 

     public Stream CorrectView(string virtualPath, Stream stream) 
     { 
      var reader = new StreamReader(stream, Encoding.UTF8); 
      var view = reader.ReadToEnd(); 
      stream.Close(); 
      var ourStream = new MemoryStream(); 
      var writer = new StreamWriter(ourStream, Encoding.UTF8); 

      var modelString = ""; 
      var modelPos = view.IndexOf("@model"); 
      if (modelPos != -1) 
      { 
       writer.Write(view.Substring(0, modelPos)); 
       var modelEndPos = view.IndexOfAny(new[] { '\r', '\n' }, modelPos); 
       modelString = view.Substring(modelPos, modelEndPos - modelPos); 
       view = view.Remove(0, modelEndPos); 
      } 

      writer.WriteLine("@using System.Web.Mvc"); 
      writer.WriteLine("@using System.Web.Mvc.Ajax"); 
      writer.WriteLine("@using System.Web.Mvc.Html"); 
      writer.WriteLine("@using System.Web.Routing"); 

      var basePrefix = "@inherits " + _webViewPageClassName; 

      if (virtualPath.ToLower().Contains("_viewstart")) 
      { 
       writer.WriteLine("@inherits System.Web.WebPages.StartPage"); 
      } 
      else if (modelString == "@model object") 
      { 
       writer.WriteLine(basePrefix + "<dynamic>"); 
      } 
      else if (!string.IsNullOrEmpty(modelString)) 
      { 
       writer.WriteLine(basePrefix + "<" + modelString.Substring(7) + ">"); 
      } 
      else 
      { 
       writer.WriteLine(basePrefix); 
      } 


      writer.Write(view); 
      writer.Flush(); 
      ourStream.Position = 0; 
      return ourStream; 
     } 
    } 

下一頁創建基於的VirtualPathProvider類(修改你的目的)

public class AssemblyResPathProvider : VirtualPathProvider 
    { 
     private readonly Dictionary<string, Assembly> _nameAssemblyCache; 

     private string _layoutPath; 
     private string _viewstartPath; 

     public AssemblyResPathProvider(string layout, string viewstart) 
     { 
      _layoutPath = layout; 
      _viewstartPath = viewstart; 

      _nameAssemblyCache = new Dictionary<string, Assembly>(StringComparer.InvariantCultureIgnoreCase); 
     } 

     private bool IsAppResourcePath(string virtualPath) 
     { 
      string checkPath = VirtualPathUtility.ToAppRelative(virtualPath); 



      bool bres1 = checkPath.StartsWith("~/App_Resource/", 
             StringComparison.InvariantCultureIgnoreCase); 


      bool bres2 = checkPath.StartsWith("/App_Resource/", 
             StringComparison.InvariantCultureIgnoreCase); 

     //todo: fix this  
      if (checkPath.EndsWith("_ViewStart.cshtml")) 
      { 
       return false; 
      } 

      if (checkPath.EndsWith("_ViewStart.vbhtml")) 
      { 
       return false; 
      } 

      return ((bres1 || bres2)); 

     } 

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


     public override VirtualFile GetFile(string virtualPath) 
     { 
      if (IsAppResourcePath(virtualPath)) 
      { 
     // creating AssemblyResourceFile instance 
       return new AssemblyResourceFile(_nameAssemblyCache, virtualPath,_layoutPath,virtualPath); 
      } 

      return base.GetFile(virtualPath); 
     } 

     public override CacheDependency GetCacheDependency(
      string virtualPath, 
      IEnumerable virtualPathDependencies, 
      DateTime utcStart) 
     { 
      if (IsAppResourcePath(virtualPath)) 
      { 
       return null; 
      } 

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

    } 

最後註冊AssemblyResPathProvider在Global.asax中

string _layoutPath = "~/Views/Shared/_Layout.cshtml"; 
string _viewstarPath = "~/Views/_ViewStart.cshtml"; 
HostingEnvironment.RegisterVirtualPathProvider(new AssemblyResPathProvider(_layoutPath,_viewstarPath)); 

這不是理想的解決方案,但它的工作對我來說很好。乾杯!