2011-06-30 88 views
1

我想將所有的CMS頁面url映射到單個控制器(PageController)和動作(Details)。Asp.net mvc 3.0樹結構頁面自定義路由

如何創建自定義路由來映射所有這些url?

/teacher 
/teacher/kindergarten 
/teacher/kindergarten/1 
/teacher/primary 
/teacher/primary/english 
/teacher/primary/language 
/teacher/primary/language/chinese 
/teacher/primary/math 
/teacher/primary/science 
/parent 
/parent/kindergarten 
/parent/primary1-3 
/parent/primary4-6 
/leader 
/leader/kindergarten 
/leader/kindergarten/1 

回答

1

如果在數據庫中這些網址,你可以在應用程序啓動時的路線圖:

var pages = siteDB.Pages.ToList(); 
    string pagePath = ""; 
    foreach (var page in pages) 
    { 
    routeVals = new RouteValueDictionary(); 
    constraints = new RouteValueDictionary(); 

    routeVals.Add("controller", "page"); 
    routeVals.Add("action", "details"); 

    constraints.Add("path", "[a-zA-Z0-9\\-]*"); 

    // any child pages? must add these routes before their parent pages. 
    var childPages = siteDB.Pages.Where(p => p.ParentPageId == page.PageId).ToList(); 
    foreach (var childPage in childPages) 
    { 
     pagePath = BuildPath(childPage); 
     RouteTable.Routes.Add(new Route(pagePath, new MvcRouteHandler()) 
     { 
     Defaults = routeVals, 
     Constraints = constraints, 
     DataTokens = 
      new RouteValueDictionary { 
      { "pageid", childPage.PageId }, 
      { "path", pagePath } 
      } 
     }); 

     // Any further child pages? (Only 3 levels supported) 
     var childSubPages = siteDB.Pages.Where(p => p.ParentPageId == childPage.PageId).ToList(); 
     foreach (var childSubPage in childSubPages) 
     { 
      pagePath = BuildPath(childSubPage); 
      RouteTable.Routes.Add(new Route(pagePath, new MvcRouteHandler()) 
      { 
       Defaults = routeVals, 
       Constraints = constraints, 
       DataTokens = 
        new RouteValueDictionary { 
       { "pageid", childSubPage.PageId }, 
       { "path", pagePath } 
       } 
      }); 
     } 
    } 

此代碼需要從那裏它們被父ID連接數據庫的頁面。

這裏的構建路徑功能,產生用於每一頁的完整路徑:

public static string BuildPath(Page page) 
{ 
    if (page.ParentPageId == 1) 
    { 
    return page.PageKey; 
    } 
    else 
    { 
    SiteDataEntities siteDB = new SiteDataEntities(); 
    string path = page.PageKey; 
    Page parent = siteDB.Pages.Find(page.ParentPageId); 
    while (parent != null) 
    { 
     path = parent.PageKey + "/" + path; 
     parent = siteDB.Pages.Find(parent.ParentPageId); 
     if (parent.PageKey == "home") break; 
    } 
    return path; 
    } 
} 
+0

謝謝山姆,這是我正在尋找。非常感謝你=) – Zayar

+0

嗨,山姆,BuildPath函數會做什麼? – Zayar

+0

剛剛添加了BuildPath函數和解釋。 –

1

上提出的解決方案是爲網頁少量唯一的工作。 因爲根據代碼:

應用程序爲每個站點頁面生成並註冊路由。結果,我們至少擁有與我們網站相同數量的路線。正如你可能知道RouteModule必須通過航線檢查航線每個人找到第一右一個,並執行正確的處理程序,控制器,動作,視圖...

還有另外兩種方式來解決這個問題:

  • 您可以創建一個從RouteBase派生的類並實現你需要的屬性和方法:分裂的URL段,確定的當前頁面的pageid,路徑,父母等

  • 您可以自定義UrlRewriteModule與custom rewrite provider填寫RouteValueDictionary。理念轉變,從樹的基礎結構中的所有請求的URL MVC默認路由:

    {控制器}/{行動}/{ID}路徑= parentlevel1/parent2/parent3/....

?可以準備兩種變體的90%相同的代碼。 該解決方案也可能是有用的,當你有不同的控制器,正確的一個,我們可以確定當前頁面(按頁數據:類型)

+0

另一種方法在這裏描述:http://stackoverflow.com/questions/379558/mvc-net-routing#379823 – Nocher