2013年8月24日 星期六

ASP.NET MVC Route 基本題 - 如何自定 URL 的子目錄路徑

對於剛學習 ASP.NET MVC 的朋友來說,Route 設定是比較少去碰到的,甚至於有人會對於 Route 是不太清楚甚至於有些模糊,這一篇講個 ASP.NET MVC 初學者常會誤解的作法,哪就是設定 URL 的子目錄路徑,尤其是已有 ASP.NET WebForm 開發經驗的朋友會把以往的開發經驗給帶到 ASP.NET MVC 的開發上,所以在這邊說明一下。

 


在開發 ASP.NET WebForm 的時候,如果想要讓網站的 URL 目錄結構有階層性,可以在網站根目錄下去建立目錄然後再加入 ASPX 檔案,

image

那麼瀏覽此網頁的 URL 就會是「http:// 網站網址 / Products / Index.aspx」

image

如果繼續往下建立子目錄的話,URL 的目錄結構就會再增加一層,

image

image

 

可是在 ASP.NET MVC 的時候想要在 URL 的目錄結構去增加下一個階層目錄時,應該怎麼做呢?

剛接觸 ASP.NET MVC 開發的朋友在還沒有認識到 Route 之前或是認識不久的情況下,可能會直接以往在 ASP.NET WebForm 的經驗拿過來用,就會有以下的作法出現:

在 Controllers 目錄下手動增加「Product」資料夾,然後新增 ProductController.cs

image

然後也在 Views 目錄下的 Home 子目錄下去新增「Product」資料夾,然後新增 Index.cshtml

image

在完成以上的設定之後,輸入 URL 卻無法照著目錄結構去顯示正確的內容,

image

如果把 URL 裡的 Home 這一層拿掉卻又出現以下的錯誤,

image

出現上面的結果後就會開始尋找怎麼正確去顯示「~/Views/Home/Product/Index.cshtml」,也許會有人找到以下的方法來讓網頁可以執行並顯示,

image

image

But … 這樣的作法是正確的嗎?
MVC 所強調的已習慣取代配置、 Controller 與 View 的對應等等,怎麼好像有些怪怪的?

image

image

 

想要讓 ASP.NET MVC 網站的 URL 結構可以有子目錄(Sub Dictionary)的路徑結構,這必須要從 Route 裡去做設定,而不是直接從 Controllers 與 Views 裡去硬加入資料夾,ASP.NET MVC 與 ASP.NET WebForm 在這方面有很大的不同,在 ASP.NET MVC 裡可以藉由 Route 的設定讓我們可以自定義 URL 的呈現與執行的對應,讓網站 URL 不必拘泥於「網站目錄結構」的限制。

 

那麼 ASP.NET MVC 要怎麼去設定有階層的 URL 呢?這邊用一個簡單的例子來做說明,以上面的例子為例,想要呈現「http:// WebSite / Home / Product / Details」,

在 HomeController 增加一個 ProductDetails Action 方法,

image

接著再建立 Action 方法相對應的 View「ProductDetails.cshtml」

image

「~/Views/Home/Product.cshtml」

image

image

 

Controller 與 View 都準備好之後,再來就是要做 Route 的設定,開啟「~/App_Start/RouteConfig.cs」檔案,

image

開啟之後只會看到一個預設的 Route 設定

image

接著我們要在預設的 route 設定上面去加入新的 route 設定,ASP.NET MVC 的 Route 設定可以有很多個,不過每個 Route 設定的名稱不可以重複,另外就是 Route 設定的匹配是有順序性的,越上面的將會優先進行匹配,有匹配到符合的 Route 設定就會執行那一個 Route 的設定內容。

我增加了以下的 Route 設定內容,

image

Route 設定的名稱為「Home_Product_SubDictionary」

對應匹配的 URL 為「Home/Product/Details/{id}」

預設對應的 Controller 為「HomeController」Action 為「ProductDetails」

限制(constraints)為只有 Controller 是 Home 以及 Action 是 ProductDetails

 

執行結果:

image

image

 

以上的作法是我們需要去自定義 URL 結構時的一些基本的設定做法,當然想要做更為複雜的 URL 結構也是可以,不過那就比較屬於進階的內容了,可以查詢網路上的一些資訊,或是可以查閱「ASP.new MVC 4 網站開發美學」「Chapter.4 - ASP.NET Routing 串起 Controller 與 View 的磨法師」此章節的內容。

假如需要的是一個可以顯示管理後台的子目錄,因為管理後台會有很多的功能,也會有很多的 Controller 需要建立,那麼就不需要用這種作法,而是需要使用「Area 區域」的作法,相關內容可以參閱以下文章「ASP.NET MVC 使用 Area - 以 Backend 後台為例」。

 

其他有關 Route 設定的相關文章:

ASP.NET MVC 資料分頁與 Route - Part.1

ASP.NET MVC 資料分頁與 Route - Part.2

ASP.NET MVC 資料分頁與 Route - Part.3

ASP.NET MVC - LowercaseRoutesMVC 讓網站的 URL 輸出為小寫

 

以上

7 則留言:

  1. 回覆
    1. 感謝你的回應,真的是過獎了

      刪除
  2. 你好小弟剛接觸不久,想請問一些問題,如果要使用mvc架構又需要分層,每個分類都有CRUD,需要如何分層呢?或者CRUD可以合併寫成呢?不然都需要在寫過一次.

    exp:
    controller 底下有一個HomeController.cs
    View\Home底下有兩個分類資料夾
    ---AA資料夾內有CRUD四個頁面index,create..
    ---BB資料夾內有CRUD四個頁面index.create..

    問題1:route 需要怎麼設定
    問題2:HomeController應該怎麼寫,AA和BB裡面的action都一樣或者有更好的作法呢?


    回覆刪除
    回覆
    1. Hello,
      不要用 ASP.NET WebForm 的架構與目錄思維來看待 ASP.NET MVC,
      我認為你才接觸 ASP.NET MVC 不久的情況下,應該要先把 ASP.NET MVC 的基礎應用給學好,
      例如你所詢問的,就是 Route 的設定應用,而不是以資料夾的方式來做,
      無論是 View 或是 Controller,個別的 View, Controller 都不應該網下去建立子目錄,

      怎麼設定呢?
      你看我這篇文章裡就已經有說明怎麼建立 URL 的下一層路徑 Home/Product/Details
      所以同樣的作法也就可以設定成你所想要的 URL 結構
      真的不是用那種「在資料夾裡再建立子目錄」的方式來看待 Route

      這裡無法用三言兩語來說明怎麼設定 Route
      Route 的設定說真的有時候也蠻複雜的,但只要了解規則就可以掌握,

      建議你可以看看「ASP.net MVC 4 網站開發美學」第四章或是「ASP.NET MVC 4 開發實戰」第四章,
      先對 Routing 有基本且正確的觀念

      對 Routing 有基本的認識之後,可以看看下面連結的文章:
      http://www.codeproject.com/Articles/641783/Customizing-Routes-in-ASP-NET-MVC

      刪除
  3. 請問一下,假設我想做的是多國語系
    zh-tw/Controller/Action

    zh-tw這個是可以固定的方式嗎?假設是英文就en/controller/action

    語系要固定出現,有辦法做到嗎?

    回覆刪除
    回覆
    1. Google 關鍵字「asp.net mvc route localization」

      刪除
    2. 不好意思,謝謝你!

      刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。

最近的留言