2009-12-28 168 views
3

我試圖做一個非常簡單的應用程序,讓我的客戶端創建自己的頁面。 困難的部分是讓他們創建自己的URL。動態URL路由ASP MVC

客戶需要填寫:(前關於我們)

  • 頁面名稱。
  • 頁面描述(例如,我們是一家大公司)。
  • 頁面URL相對(例如:/關於)

當客戶輸入此信息並保存,應保存在數據庫中。

我可以很容易地創建一個名爲「Page」的控制器,其值爲「ID」,當用戶輸入「www.someurl.com/Page/1」時,彈出新創建的頁面。

但我真正想要的是用戶寫「www.someurl.com/About」,然後彈出頁面。

如何使用ASP MVC實現某種動態重寫/路由代碼。

回答

6

我的想法是在'Page'表中創建一個名爲'Slug'的字段。當你的用戶創建一個新頁面時,他們必須填寫'Slug'字段並輸入他們想要在URL中看到的內容(例如:想要的頁面 - 「關於」,slug - 「about」| page wanted - 「請參閱我們的贊助商「,slug - 」看我們的贊助商「|等等)。如果你願意,你可以用一點點的javascript自動化這個過程。

創建像這樣的路線:

routes.MapRoute(
    null, 
    {slug}, 
    new { controller = "Page", action = "ChoosePage" }); 

創建的操作方法如下所示:

[AcceptVerbs(HttpVerbs.Get)] 
public ViewResult ChoosePage(string slug) 
{ 
    //Logic to display page 
} 

基本上它的工作就像你把頁面ID的URL的想法,但它會更清潔,它會使用'slug'來執行數據庫查找,而不是頁面ID。

+1

務必將路線放置在上你的路線路線頁面。這樣,如果用戶創建了一條與硬編碼路由衝突的路由,則會執行硬編碼路由,確保您的應用程序不會中斷。此外,請創建一個已被使用的「已禁用」路由列表你的申請。 – Omar 2009-12-29 02:41:05

+0

我在「默認」路線下面添加了它,但是它不起作用。當我將它放置在「默認」路線的正上方時,它工作正常嗎? – Martin 2009-12-30 23:58:14

+0

如果我想要用戶創建自己的關卡(例如/ News/my-news-item),該怎麼辦。此解決方案僅支持一個級別,將其擴展到「未知級別」解決方案的最佳方式是什麼? – Martin 2009-12-31 00:05:50

7

由於關於本網站路由的問題數量表明,正確處理多個可能重疊的路由即使對於程序員也是非常棘手的。將這種廣泛的功能交付給終端用戶是令人恐懼的。

要回答你的問題,在應用程序啓動時從數據庫中讀取「自定義」路由並像往常一樣映射它們非常簡單。您通常不會在應用程序執行期間執行此操作,因爲路由列表將在多個線程之間共享。如果您深入瞭解路由源代碼,您可能會找到一種方法來保護路由表的「重建」,如果您確定在執行期間必須執行此操作。

但是,我強烈建議您使用您的「網站」控制器的想法。考慮以下幾點:路由既用於解析傳入的URI 以生成URI。如果您的應用程序中甚至存在一個使用ActionLink而不是RouteLink的案例,那麼請考慮用戶添加的路線可能會破壞整個網站。這意味着即使用戶意識到他們已經造成了錯誤,用戶也無法修復他們的錯誤。

3

我想到的最好的想法是使用「最後一種情況」的想法。

基本上你有這種情況。

1-正常路由(例如:controller/action/id route)。
2-您可能設置的任何特殊路線/區域(例如:admin)
3-編寫一條全包路線。此路線將在數據庫中搜索由路線命名的頁面。如果這條路線不存在,它將會拋出一個404頁未找到的錯誤。

2

這就是最終代碼的樣子,感謝所有幫助過你的人!

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      "Home", 
      "", 
      new { controller = "Home", action = "Index" } 
     ); 

     routes.MapRoute(
      "Account", 
      "Account/{action}", 
      new { controller = "Account", Action = "Index" } 
     ); 

     routes.MapRoute(
      "Page", 
      "{*slug}", 
      new { controller = "Page", action = "ChoosePage" } 
     ); 

    } 
2

這可以通過以下方式進行:

1.Insert新的RouteTable

RouteTable.Routes.Insert(1,new Route("Test", new RouteValueDictionary(new { controller = "Page", action = "ChoosePage" ,pagename="Test" }), new MvcRouteHandler())); 

public ActionResult ChoosePage(string pagename) 
{ 
    return View(pagename); 
} 

該頁面的路線這將在運行時解決新創建的頁面的路線,但這需要保存在數據庫中。

  • 寫代碼來檢索數據庫中的所有路線,並在Global.asax.cs中寫文件的Application_Start()