2017-11-18 106 views
0

我有一些简单的视图,例如居住在主控制器中的“关于我们”和“联系我们”。当没有控制器通过url时,MVC路由规则默认为主控制器

我宁愿网址没有回家参加它像www.xyz.com/ContactUs,而不是www.xyz.com/Home/ContactUs

我补充说,需要照顾这一点,但破坏其它控制器在URL中没有指定动作时,一条新的路线

// Home Routes 
RouteTable.Routes.MapRoute("HomeRoute", "{action}", new { controller = "Home", action = "Index" }); 

// Default 
RouteTable.Routes.MapRoute("Default", "{controller}/{action}", new { controller = "Home", action = "Index" }); 

很明显,这是因为路由引擎无法确定哪个路由用于像www.xyz.com/ContactUs这样的url,并使用第1个匹配。

我也知道我可以为每个控制器,但这似乎是一种效率较低的方式。我不想结束30个控制器只是为了包装每个视图的一个空视图动作。

我可能会最终为每个控制器做出反应,但是想知道是否有办法制作一条类似于的路线“如果只传递了一个参数,首先检查它是否与控制器相匹配,如果不是假设它是家庭控制器的话。“

+0

请参阅[为什么要在asp.net mvc中的常用路由之前先映射特殊路由?](https://stackoverflow.com/a/35674633/)。您需要*东西*告诉MVC何时跳过第一条路线并移至第二条路线。最简单的选择是在你的路由配置中使用静态URL,比如'ContactUs',而不是使用'{action}'(它可以真正匹配任何东西)。属性路由是另一种选择,但它有自己的一套问题(即,在创建属性时默认情况下,您必须知道属性具有* undefined order *,因此您可能必须显式设置Order属性) 。 – NightOwl888

回答

1

您可以使用MVC属性路由来创建这些SEO友好路线。

[Route("About")] 
public ActionResult About() 
{ 
    return View(); 
} 
[Route("Contact")] 
public ActionResult Contact() 
{ 
    return View(); 
} 

假设您启用了属性路由。

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

    routes.MapMvcAttributeRoutes(); 

    routes.MapRoute(
     name: "Default", 
     url: "{controller}/{action}/{id}", 
     defaults: new { controller = "Home", action = "Index", 
                  id = UrlParameter.Optional } 

    ); 
} 

另一种选择是具有类似于你已经尝试了什么2个路线注册。它将用于处理像yourSite/About/这样的请求(它将呈现在您的HomeController中执行About动作)。但是当你请求yourSite/Books之类的东西时,它将不会被IndexBooks控制器的操作处理,因为该url与我们为SEO友好路线定义的第一个模式相匹配,并且如果在HomeController中没有Books动作方法,您将获得404! (如果你没有这条路线注册,它会工作)

routes.MapRoute(
    name: "JustActions", 
    url: "{action}", 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

另一种选择,如果你不喜欢的属性路由的方法,你可以为这个特定的路线逐一登记在RegisterRoutes方法途径。 (这类似于通过属性路由定义路由,但我们在一个地方执行,确保在通用默认路由之前注册特定路由)。我个人比较喜欢属性路由,因为我觉得它更具可读性。

+0

我想我没有考虑只为每个视图制作一个特定的路线,而不是试图制作一个通用的路线。在性能,测试等方面使用属性路由有什么缺点吗? – user3953989

+1

我没有意识到性能开销。我个人更喜欢属性路由方法,而不是单独的特定路由定义,因为我觉得它更具可读性。 – Shyju

+0

当然,使用属性路由会带来性能开销。它依靠Reflection来读取您放入属性的值。但是,这种开销通常仅限于应用程序启动。 – NightOwl888