2013-12-16 15 views
8

Stworzyłem modułowy projekt MVC, aby załadować inny specjalny projekt WWW w tym samym środowisku wykonawczym.MVC: Nie znaleziono widoku "~ /.../ Index.cshtml"

Inne projekty znajdują się w folderze w katalogu głównym witryny o nazwie "Moduły". Używam atrybutu PreApplicationStartMethod do ładowania innych zestawów wewnątrz podkatalogów podczas rozruchu.

Dodałem specjalne trasy, aby kierować każdy moduł z ograniczeniami przestrzeni nazw.

muszę utworzyć klasę, która implementuje RazorViewEngine przesłonić viewPath gdy połączenie jest wykonane dla elementu w module: ~/Views/Home/Index.cshtml -> ~/Moduły/ModuleTest/widoki /Home/Index.cshtml.

Index() metoda wewnątrz dynamicznie załadowanego biblioteki powodzeniem nazywa ale mam błąd, gdy widok jest renderowany:

Zobacz następujący obraz: http://i.imgur.com/KoTgxg2.png

Ramy mi powiedzieć, w zasadzie, że został znaleziony, ale go nie renderuje. Czy ktoś ma jakiś pomysł, dlaczego ramy odmówić renderowania?

Błąd serwera w aplikacji "/".

Widok z "~/Modules/ModuleTest/Views/Home/Index.cshtml" nie został utworzony.

Opis: Wystąpił nieobsługiwany wyjątek podczas wykonywania bieżącego żądania WWW. Sprawdź ślad stosu, aby uzyskać więcej informacji o błędzie i skąd pochodzi w kodzie.

Szczegóły wyjątku: Wyjątek System.InvalidOperationException: Widok z "~/Modules/ModuleTest/Views/Home/Index.cshtml" nie został utworzony.

  • Wyjątek
 
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 
  • Controller

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

    @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

Czy Twój widok jest wolny od błędów? –

+0

Co to jest tryb kompilacji? Czy zmiana go na compilationMode = "Always" help? –

+0

Próbuję tego, ale nic nie zmienia, niestety – Lex2193

Odpowiedz

8

znalazłem problem debugowania do http://aspnetwebstack.codeplex.com/.

Właściwie ładuję bibliotekę, która zawiera kontrolery z innego folderu niż bin w mojej klasie ModulesContainer (zobacz pytanie).Ale wewnątrz System.Web.Mvc.dll, jedna metoda spróbować znaleźć mój typ regulatora wykonując Assembly.Load() w domyślnym katalogu, jego dlaczego BuildManager.GetCompiledType() powrót zerowy.

znalazłem prosty sposób zastąpić tę metodę z:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;

i

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)); 
    }

prostu szukam w moim gotowych dll cache znajdź już załadowany zespół.

+2

To wygląda na użyteczne, ale gdzie jest zdefiniowana i wypełniona zmienna _modules? – Jeremy

0

@ Lex2193: Znalazłem problem z twoją odpowiedzią. Kiedy przy użyciu kodu to działa dobrze z wyjątkiem sytuacji, w której odwołuje Zgromadzenie innego odniesienia, od którego zależy:

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

Podczas korzystania z modułu obiektu z [D], który ma w nim kilka połączeń do coś w [DD]. Nie zadziała w przypadku wyjątku TypeLoad. Z powodu prośby o złożenie. Więc edytowałem kod do pierwszego wyszukiwania dla modułu:

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)); 
} 
Powiązane problemy