簡體   English   中英

ASP.NET MVC 2 urls / routes如何與控制器相關的視圖?

[英]ASP.NET MVC 2 How are urls/routes, views related to controllers?

有人可以解釋一下MVC 2中路由器與控制器的關聯方式嗎? 目前,我在/Controllers/HomeController.cs中有一個控制器和一個視圖/Home/Index.aspx。

我的路線注冊方法如下:

 public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
            routes.MapRoute(
               "Default",
                // Route name
               "{controller}/{action}/{id}",
                // URL with parameters
               new { controller = "Home", action = "Index", id = "" }
                // Parameter defaults
              );
        }

如果我請求URL: http:// localhost / Home / Index ,則HomeController.Index()正確處理請求。

但是,對於我的生活,我無法弄清楚url / Home / Index如何指向HomeController。 據我所知,視圖aspx沒有引用HomeController,HomeController沒有引用視圖,路由表也沒有明確提到HomeController。 這神奇地發生了什么? 當然我錯過了一些明顯的東西。

然后

這是ASP.NET MVC中的約定。

使用DefaultControllerFactory時,此約定隱藏在內部密封類System.Web.Mvc.ControllerTypeCache (Microsoft通常用於編寫內部密封類)。 在里面你會發現一個名為EnsureInitialized的方法,如下所示:

public void EnsureInitialized(IBuildManager buildManager)
{
    if (this._cache == null)
    {
        lock (this._lockObj)
        {
            if (this._cache == null)
            {
                this._cache = GetAllControllerTypes(buildManager).GroupBy<Type, string>(delegate (Type t) {
                    return t.Name.Substring(0, t.Name.Length - "Controller".Length);
                }, StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string, Type>, string, ILookup<string, Type>>(delegate (IGrouping<string, Type> g) {
                    return g.Key;
                }, delegate (IGrouping<string, Type> g) {
                    return g.ToLookup<Type, string>(t => t.Namespace ?? string.Empty, StringComparer.OrdinalIgnoreCase);
                }, StringComparer.OrdinalIgnoreCase);
            }
        }
    }
}

注意如何進行分組。 因此,基本上,DefaultControllerFactory將查看實現Controller基類的類型的所有引用程序集,並從名稱中刪除“Controller”。

如果你真的想詳細剖析ASP.NET MVC的管道,我會推薦你​​這篇優秀的文章

ASP.NET MVC附帶的默認視圖引擎適用於以下約定:

你有這樣的文件夾結構:

- Controllers\
|-  HomeController.cs
- Views\
|- Home\
|-- Index.aspx
|- Shared\

當請求進入並匹配RegisterRoutes方法中定義的路由時(請參閱URL路由等更多內容),然后調用匹配的控制器:

routes.MapRoute(
  "Default", // Route name, allows you to call this route elsewhere
  "{controller}/{action}/{id}", // URL with parameters
  new { controller = "Home", action = "Index", id = "" } // Parameter defaults
  );

在默認路由中,您還指定了默認控制器(沒有“Controller”后綴) - 路由引擎將自動將Controller添加到控制器名稱中 - 以及默認操作。

在您的控制器中,您可以調用簡單方法:

public ActionResult Index(){
  return View();
}

然后,默認視圖引擎在“Views”文件夾(約定)中的名為“Home”的文件夾(與控制器相同)中查找名為Index的aspx文件(與操作相同)。

如果它沒有在那里找到,它還將在共享文件夾中查找索引頁面。

來自ASP.NET MVC Nerd Dinner示例章節

在解析視圖模板時,ASP.NET MVC應用程序默認使用基於約定的目錄命名結構。 這允許開發人員在從Controller類中引用視圖時避免必須完全限定位置路徑。 默認情況下,ASP.NET MVC將在應用程序下的\\Views\\[ControllerName]\\目錄中查找視圖模板文件。

\\Views\\Shared子目錄提供了一種存儲視圖模板的方法,這些模板在應用程序中的多個控制器之間重復使用。 當ASP.NET MVC嘗試解析視圖模板時,它將首先在\\Views\\[Controller]特定目錄中進行檢查,如果找不到視圖模板,它將在\\Views\\Shared目錄中查找。

在命名單個視圖模板時,建議的指導是使視圖模板與導致其呈現的操作方法共享相同的名稱。 例如,在我們的“索引”操作方法上方使用“索引”視圖來呈現視圖結果,“詳細信息”操作方法使用“詳細信息”視圖來呈現其結果。 這樣可以輕松快速查看與每個操作關聯的模板。

當視圖模板與控制器上調用的操作方法同名時,開發人員無需顯式指定視圖模板名稱。 我們可以只將模型對象傳遞給View()輔助方法(不指定視圖名稱),ASP.NET MVC會自動推斷我們要使用\\Views\\[ControllerName]\\[ActionName]視圖模板磁盤來渲染它。


編輯添加:

我設置的一些示例路由,顯式設置控制器是:

routes.MapRoute(
  "PhotoDetailsSlug",
  "Albums/{albumId}/{photoId}/{slug}",
  new {controller = "Albums", action = "PhotoDetails"},
  new {albumId = @"\d{1,4}", photoId = @"\d{1,8}"}
  );

在這里,我明確指出我正在使用Albums控制器和PhotoDetails操作,並將各種ID傳遞給該操作。

在操作索引內部有一個語句return View() 返回空白視圖時,DefaultViewEngine會在幾個默認文件夾中搜索Controller方法的名稱(特別是在FindView方法中)。 其中一個是Views / Home目錄,因為Home是控制器的名稱。 在那里它找到索引文件,並使用它來顯示結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM