2012-01-31 46 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