方法一,可以在目錄中命名一個和目錄同樣名字的controller,然后用特性來進行設置,比如:
Controllers/myfolder/myfolderController.cs
我建立了上述結構,注意 myfolder就是我自己建立的目錄,因此控制器名字也要交myfolder。
然后在控制器里面寫:
[HttpGet]
[ActionName("Index")]
public ActionResult abcd(string id){
retrun View("~/Views/Home/About.cshtml");
}
Mvc多級Views目錄 asp.net mvc4 路由重寫及 修改view 的尋找視圖的規則 一般我們在mvc開發過程中,都會碰到這樣的問題。頁面總是寫在Views文件夾下,而且還只能一個Controller的頁面只能寫在相應的以Controller名命名的文件夾下。如果我們寫到別處呢?那么肯定會報錯。這是mvc中一個約定俗成的一個規定,必須這樣寫。
1.正常的項目目錄,如下圖:
我們要訪問Index頁面,只需要輸入Home/Index就可以訪問了。我們之所以能夠這樣訪問,是因為我們在項目創建之初系統就默認配置了一個默認的路由。我們可以按照這個默認的路由規則進行訪問。
2.那么我們再來看我們需要的訪問方式,如下圖
如果我們要訪問Admin下的TestController里面的Index頁面,那么我們輸入Test/Index,這個肯定不行的。因為TestController根本就不在Controllers的根目錄下,而是在Controllers/Admin下,這樣我們根本就找不到Test這個Controller。那么我們輸入Admin/Test/Index,那么我們就需要添加一個路由配置了,因為以前的默認路由只能通過{Controller}/{Action}/{Id}這種方式訪問,就是必須以Controller開頭。我們重新配置的路由如下:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//路由規則匹配是從上到下的,優先匹配的路由一定要寫在最上面。因為路由匹配成功以后,他不會繼續匹配下去。
routes.MapRoute(
"Admin", // 路由名稱,這個只要保證在路由集合中唯一即可
"Admin/{controller}/{action}/{id}", //路由規則,匹配以Admin開頭的url
new { controller = "Home", action = "Index", id = UrlParameter.Optional } //
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
View Code 那么我們這個時候再次輸入Admin/Test/Index,能找到Views/Admin/Test/Index.cshtml這個頁面嗎?顯然是不能的,因為除了路由配置怎么訪問Controller外,尋找Views里面的頁面也有自己的規則。測試結果肯定是找不到頁面,我們看看錯誤信息就知道他是怎么尋找cshtml頁面了。
“The following locations were searched” 翻譯過來就是"以下地址被搜索過"。那么他只搜索這些地址,這里我只寫razor視圖的地址,寫成通配符就是:
•Views/{1}/{0}.cshtml
•Views/Shared/{0}.cshtml
{1}表示Controller的名稱,{0}表示視圖名稱,Shared是存放模板頁的文件夾。一看就很清楚了。這個就是尋找視圖的規則,所以我們存放在Admin/Test/Index.cshtml的存放規則就不滿足。那么我們修改下,如下圖:
直接將Test文件夾存放在Views下面,那么我們就滿足這個尋找視圖的規則了,我們輸入Admin/Test/Index,也確實訪問成功了。
但是這個方式的存儲肯定不是我們需要的,既然我們Controller區分存放了,我們肯定也希望Views也能夠這樣存放的。
3.那么我們進入正題,修改他的尋找視圖的規則,讓他能夠按照我們的規則來訪問,就像修改路由一樣。
在項目中新建立一個cs類MyViewEngine,繼承RazorViewEngine。代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcRoute.MvcEx
{
public sealed class MyViewEngine : RazorViewEngine
{
public MyViewEngine()
{
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Admin/{1}/{0}.cshtml"//我們的規則
};
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
}
View Code 然后將這個規則注冊到系統中,在global中注冊一下,這樣我們就可以通過自己的方式來訪問了。global注冊如下:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
RegisterView();//注冊視圖訪問規則
}
protected void RegisterView()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyViewEngine());
}
View Code 結果如下圖: