2009-12-28 171 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()