2013-12-16 16 views
8

我已經創建了一個模塊化的MVC項目來在同一個運行時加載其他特殊的web項目。MVC:在'〜/.../ Index.cshtml'找到的視圖沒有被創建

其他項目位於名爲「模塊」的網站根目錄的文件夾中。 我正在使用屬性PreApplicationStartMethod在引導時將其他程序集加載到子目錄中。

我已經添加了特殊路由,以使用命名空間約束來定位每個模塊。

我已創建誰實現RazorViewEngine覆蓋viewPath當呼叫的模塊中的元素做了一個類:〜/查看/主頁/ Index.cshtml - >〜/模塊/ ModuleTest /瀏覽次數/Home/Index.cshtml。

動態加載庫中的指數()方法調用成功,但我得到一個錯誤時,視圖顯示:

見下面的圖片:http://i.imgur.com/KoTgxg2.png

框架告訴我基本上是在查看已被發現,但他不會呈現它。 有沒有人有任何想法爲什麼框架拒絕渲染它?

'/'應用程序中的服務器錯誤。

'〜/ Modules/ModuleTest/Views/Home/Index.cshtml'中的視圖未創建。

描述:執行當前Web請求期間發生未處理的異常。請查看堆棧跟蹤以獲取有關該錯誤的更多信息以及源代碼的位置。

異常詳細信息:System.InvalidOperationException:在'〜/ Modules/ModuleTest/Views/Home/Index.cshtml'中找到的視圖未創建。

  • 異常
 
Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 

[InvalidOperationException: The view found at '~/Modules/ModuleTest/Views/Home/Index.cshtml' was not created.] 
    System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +362 
    System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +431 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +116 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +106 
    System.Web.Mvc.Async.c__DisplayClass28.b__19() +321 
    System.Web.Mvc.Async.c__DisplayClass1e.b__1b(IAsyncResult asyncResult) +185 
    System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40 
    System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44 
    System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller) +39 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39 
    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39 
    System.Web.Mvc.MvcHandler.b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +39 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 
    System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9514812 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18408 
  • 控制器

    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      return View(new TestModel() { Value = "Bla" }); 
     } 
    } 
  • 查看
 

    @using Easily.ModuleTest.Models; 
    @{ ViewBag.Title = "Test Index"; } 
    @model TestModel 
    @Model.Value 

  • CustomRazorViewEngine

    public class CustomRazorViewEngine : RazorViewEngine 
    { 
     public CustomRazorViewEngine() 
     { 
      List tmpViewLocationFormats = new List(ViewLocationFormats); 
      List tmpMasterLocationFormats = new List(MasterLocationFormats); 
      List tmpPartialViewLocationFormats = new List(PartialViewLocationFormats); 
      foreach (string moduleDirectory in EasilyModulesContainer.Modules.Select(x => x.Directory)) 
      { 
       foreach (string viewLocationFormat in ViewLocationFormats) 
        tmpViewLocationFormats.Add(viewLocationFormat.Replace("~/", string.Format("~/{0}/{1}/", Constants.ModulesDirectory, moduleDirectory))); 
       foreach (string masterLocationFormat in MasterLocationFormats) 
        tmpMasterLocationFormats.Add(masterLocationFormat.Replace("~/", string.Format("~/{0}/{1}/", Constants.ModulesDirectory, moduleDirectory))); 
       foreach (string partialViewLocationFormat in PartialViewLocationFormats) 
        tmpPartialViewLocationFormats.Add(partialViewLocationFormat.Replace("~/", string.Format("~/{0}/{1}/", Constants.ModulesDirectory, moduleDirectory))); 
      } 
      ViewLocationFormats = tmpViewLocationFormats.ToArray(); 
      MasterLocationFormats = tmpMasterLocationFormats.ToArray(); 
      PartialViewLocationFormats = tmpPartialViewLocationFormats.ToArray(); 
     } 

     protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
     { 
      return base.CreateView(controllerContext, GetPath(controllerContext, viewPath), masterPath); 
     } 

     protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
     { 
      return base.CreatePartialView(controllerContext, GetPath(controllerContext, partialPath)); 
     } 

     private string GetPath(ControllerContext controllerContext, string path) 
     { 
      if (!controllerContext.RouteData.Values.ContainsKey("_module")) 
       return path; 
      Module module = ModulesContainer.Modules.SingleOrDefault(x => x.Name == controllerContext.RouteData.GetRequiredString("_module")); 
      return path.Replace("~/", string.Format("~/{0}/{1}/", Constants.ModulesDirectory, module.Directory)); 
     } 
    } 
+0

是您的看法沒有錯誤嗎? –

+0

什麼是編譯模式?是否將其更改爲compilationMode =」始終‘幫助? –

+0

我試試這個,但它不是改變任何不幸 – Lex2193

回答

8

我通過調試到http://aspnetwebstack.codeplex.com/發現了這個問題。

我實際上從我的ModulesContainer類(請參閱問題)中加載包含來自另一個文件夾而不是bin的控制器的庫。但裏面System.Web.Mvc.dll程序,一個方法試圖通過在默認目錄做一個Assembly.Load()找到我的控制器類型,它爲什麼BuildManager.GetCompiledType()回報

我發現了一個簡單的方法來重寫此方法有:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;

private static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     if (args.RequestingAssembly != null) 
      return args.RequestingAssembly; 
     Module module = _modules.SingleOrDefault(x => x.Assembly.FullName == args.Name); 
     if (module != null) 
      return module.Assembly; 
     throw new Exception(string.Format("Unable to load assembly {0}", args.Name)); 
    }

我只是看看我的預建 DLL緩存裏面找到已經加載的程序集。

+2

這看起來很有用,但_modules變量在哪裏定義和填充? – Jeremy

0

@ Lex2193:我在你的答案中發現的問題。 當我用你的代碼,除了情況,其中引用的組件具有它所依賴的另一個參考它運作良好:

Module [M] => Dependency [D] => DeepDependency [DD] 

當您在模塊對象從使用[d]已在它的一些調用[DD]中的內容。它會在TypeLoad異常時失敗。因爲要求組裝。 所以我編輯的代碼首先爲模塊搜索:

public static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    Assembly module = modules.SingleOrDefault(x => x.FullName == args.Name); 
    if (module != null) 
     return module; 

    if (args.RequestingAssembly != null) 
     return args.RequestingAssembly; 

    throw new Exception(string.Format("Could not load file or assembly {0}", args.Name)); 
}