2012-01-31 55 views
0

我目前正在寫一篇新聞文章方面的應用程序,我添加了新的路線(新文章)到我的RouteTable,似乎添加罰款,但路由無法訪問?動態添加到RouteTable不工作

我使用的代碼如下:

var routes = RouteTable.Routes; 
using (routes.GetWriteLock()) 
{ 
    var url = contentHelper.GetPageUrl(page); 
    routes.MapRoute(page.Id.ToString(), url, new { controller = "Cms", action = "Index", id = url }, new[] { "Web.Controllers.CmsController" }); 
} 

新的URL,正如我前面所說,加入到RouteTable.Routes,但我不能讓頁面。在重新啓動後,它由Global.asax中的RegisterRoutes拾取並正常工作。

,你可以在此有何啓示將是巨大的,因爲我想做到這一點,而不用對應用程序重啓

編輯

這是從我的Global.asax

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

     routes.MapRoute("LogOff", "LogOff", new { controller = "Account", action = "LogOff" }); 

     routes.MapRoute(
       "News", // Route name 
       "News/",// URL with parameters 
       new { controller = "NewsPage", action = "Index" }, // Parameter defaults 
       new[] { "Web.Controllers.NewsController" } 
      ); 

     //register all content pages 
     var urls = new ContentPageHelper().GetAllUrls(); 
     foreach (var url in urls) 
     { 
      routes.MapRoute(url.Key.ToString(), url.Value, new { controller = "Cms", action = "Index", id = url.Key }, new[] { "Web.Controllers.CmsController" }); 
     } 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}",// URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
     ); 
    } 

回答

4

的問題是,調用RouteTable.MapRoute將該路由表的末尾。您的默認路由通常是要添加到表中的最後一個路由,但由於您在建立路由表後已動態調用RouteTable.MapRoute,所以默認路由在到達您新添加的路由之前正在被命中。

我對這個問題的解決方案如下。

public static void AddContentRoute(this RouteCollection routes, Data.UrlMap map, bool needsLock = false) 
    { 
     var route = new Route(map.Url, new MvcRouteHandler()); 
     route.Defaults = new RouteValueDictionary(new 
     { 
      controller = "Content", 
      action = "Display", 
      id = map.Id, 
      type = map.Type 
     }); 

     if (needsLock) 
     { 
      using (routes.GetWriteLock()) 
      { 
       routes.Insert(0, route); 
      } 
     } 
     else 
     { 
      routes.Insert(0, route); 
     } 
    } 

這基本上做什麼RouteTable.MapRoute做,但插入表中,而不是末端的頂部的路線。

如果您還有其他路線需要坐在表格的頂部,您可能需要修改此解決方案。

+0

如何確定添加路由是否需要鎖定(當您將其作爲參數傳遞時)? – Rodolfo 2012-10-18 18:47:47

+0

我寫的函數基本上是RouteTable.MapRoute所做的一個副本(查看源代碼並親自查看)。在線程情況下使用鎖定,在大多數情況下不需要。 – Brendan 2012-10-18 20:44:08

-1

你爲什麼會在飛行中創建一條路線?當應用程序自行重新啓動應用程序時,這不會破壞目的,所有這些路線都需要重新創建才能正常工作

爲什麼不創建一個只處理您的cms所有請求的路由?

routes.MapRoute("CmsPage", "{page}", new { controller = "Cms", action = "Index"}, new [] { "Web.Controllers.CmsController" }); 

,如果你這樣做,所以它不能與其他路線/控制器應用程序中的碰撞,你總是可以前綴的所有CMS生成與網頁的頁面。我正在爲我現在創建的CMS網站執行此操作。

routes.MapRoute("CmsPage", "pages/{page}", new { controller = "Cms", action = "Index"}, new [] { "Web.Controllers.CmsController" }); 

你在你的控制器行動將與此類似

public ActionResult Index(string page) 
{ 
    // logic to load page 
    return View(); 
} 
+0

我已經在global.asax中完成了這項工作,但是如果路由是在global.asax中創建的,那麼在創建新頁面時無需重新啓動應用 – JamesStuddart 2012-01-31 16:03:37

+0

,它們應該儘快可用他們被創建。當你的Action被調用時,你如何檢索你的頁面?你把頁面存儲在數據庫中? – 2012-01-31 16:07:53

+0

在網址中添加'Pages /'也是一種醜陋而且很冒險的做法,它不會從SEO的角度做任何積極的事情。 請參閱global.asax的編輯 – JamesStuddart 2012-01-31 16:08:30