MVC Routing below sub folders

I need some help with the routing. I tried to find existing Questions-Answers but nothing that is helping me. In case there is a answer already, please link it.

My structure:

/Controller
--/Root
----/HomeController.cs
/Views
--/Root
----/Home
------/Index.cshtml

The problem is, that the Index.cshtml cannot be found.

The view 'Index' or its master was not found. The following locations were searched:

~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

Stacktrace:

System.Web.Mvc.ViewResult.FindView(ControllerContext context) +382 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +116 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.<>c__DisplayClass1a.b__17() +23 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func 1 continuation) +245<br /> System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +22 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList 1 filters, ActionResult actionResult) +176 System.Web.Mvc.Async.<>c__DisplayClass2a.b__20() +75 System.Web.Mvc.Async.<>c__DisplayClass25.b__22(IAsyncResult asyncResult) +99 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Async.<>c__DisplayClass4.b__3(IAsyncResult ar) +16 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.S ystem.Web.HttpApplication.IExecutionStep.Execute() +9721605 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

The routing is this:

routes.MapRoute(
    name: "Home",
    url: "Root/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    ).DataTokens.Add("app", "Home");

Is there something I missed?


By default, MVC looks for views in ~/Views/YourControllerName folder. Looks like you have a directory called root for your controllers and views. I am not sure why you want to do that. If you are doing this to organize code logically in your project, you should consider Areas.

You may create a new area called root. This will create a directory called root under ~/Areas . You can create controllers and views under that. When you define your routes , you do not need the to include the word Root in your url as you will have an Area registration starts with the word Root (which you can customize)

But if you really want to not use areas, but want to keep your views under ~/Views/root directory, You can create a custom view engine and specify where to look for the view files.

public class MyCustomViewEngine : RazorViewEngine
{
    public MyCustomViewEngine()
    {
        string[] viewLocationFormatArr=new string[4];
        viewLocationFormatArr[0] = "~/Views/root/{1}/{0}.cshtml";
        viewLocationFormatArr[1] = "~/Views/Root/{1}/{0}.vbhtml";
        viewLocationFormatArr[2] = "~/Views/Shared/{1}/{0}.vbhtml";
        viewLocationFormatArr[3] = "~/Views/Shared/{1}/{0}.vbhtml";
        this.ViewLocationFormats = viewLocationFormatArr;

        string[] masterLocationFormatArr = new string[4];
        masterLocationFormatArr[0] = "~/Views/root/{1}/{0}.cshtml";
        masterLocationFormatArr[1] = "~/Views/root/{1}/{0}.vbhtml";
        masterLocationFormatArr[2] = "~/Views/Shared/{1}/{0}.vbhtml";
        masterLocationFormatArr[3] = "~/Views/Shared/{1}/{0}.vbhtml";
        this.MasterLocationFormats = masterLocationFormatArr;

        string[] partialViewLocationFormatArr = new string[4];
        partialViewLocationFormatArr[0] = "~/Views/root/{1}/{0}.cshtml";
        partialViewLocationFormatArr[1] = "~/Views/root/{1}/{0}.vbhtml";
        partialViewLocationFormatArr[2] = "~/Views/Shared/{1}/{0}.vbhtml";
        partialViewLocationFormatArr[3] = "~/Views/Shared/{1}/{0}.vbhtml";
        this.ViewLocationFormats = partialViewLocationFormatArr;

    }
}

Make sure to register this custom view engine in the Application_Start event.

ViewEngines.Engines.Clear();
var ourViewEngine = new MyCustomViewEngine();
ViewEngines.Engines.Add(ourViewEngine);

Detailed blog about rendering views from custom location is here.

链接地址: http://www.djcxy.com/p/72700.html

上一篇: 当我在服务器中调用RedirectToAction时发生错误

下一篇: 子文件夹下的MVC路由