MVC区域与HTML Slug:如何缩短应用URL路径?
当然可行!咱们一步步来解决这个URL缩短的问题,分两种情况给你拆解方案:
方案一:省略
Details动作名(保留Discussion区域前缀) 这个方案实现你想要的 www.sitename.com/Discussion/Articlev1/id/cool-html-article 格式,只需要调整区域注册里的路由顺序和模板即可:
修改区域注册代码
把你的View_Article路由放在默认路由前面(路由匹配是从上到下执行的,更具体的路由要优先注册),同时修改路由模板去掉Details部分,直接把id和articleTitle绑定到Details动作:
public override void RegisterArea(AreaRegistrationContext context) { // 优先注册具体的文章详情路由 context.MapRoute( "View_Article", "Discussion/Articlev1/{id}/{articleTitle}", // 去掉了原模板里的Details new { controller = "Articlev1", action = "Details", id = UrlParameter.Optional, articleTitle = "" }, new { id = @"\d+" } // 给id加数字约束,避免和其他路由冲突 ); // 再注册区域默认路由 context.MapRoute( "Discussion_default", "Discussion/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); }
为什么这样改?
- 路由模板去掉
Details后,当用户访问Discussion/Articlev1/123/cool-html-article时,MVC会自动把请求映射到Articlev1控制器的Details动作,参数id=123、articleTitle=cool-html-article。 - 给
id加\d+正则约束,确保只有数字ID的请求才匹配这个路由,避免和其他控制器/动作的路由冲突。
方案二:完全去掉
Discussion区域前缀(直接Articlev1/id/cool-html-article) 这个方案实现更简洁的URL格式,但需要在全局路由配置里注册路由(而不是区域注册),并且要优先于区域路由执行:
全局路由配置(RouteConfig.cs)
打开项目根目录的App_Start/RouteConfig.cs,在区域路由注册前(注意顺序!)添加以下路由:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 优先注册文章详情的全局路由 routes.MapRoute( "Global_View_Article", "Articlev1/{id}/{articleTitle}", new { controller = "Articlev1", action = "Details", id = UrlParameter.Optional, articleTitle = "" }, new { id = @"\d+" }, new[] { "YourProjectName.Areas.Discussion.Controllers" } // 指定区域控制器的命名空间,避免冲突 ); // 然后注册区域路由 AreaRegistration.RegisterAllAreas(); // 最后注册全局默认路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
关键注意点
- 必须指定区域控制器的命名空间:因为
Articlev1控制器在Discussion区域里,全局路由需要明确知道去哪个命名空间找这个控制器,否则会和根目录下的同名控制器(如果有的话)冲突。 - 路由顺序绝对不能乱:全局文章路由要放在
AreaRegistration.RegisterAllAreas()前面,否则区域的默认路由会先匹配请求,导致你的短URL失效。
额外注意事项
- 生成URL时指定路由名称:在View里生成文章链接时,要明确使用路由名称(比如
"View_Article"或"Global_View_Article"),而不是默认的Html.ActionLink,这样才能生成你想要的短URL:@Html.RouteLink("查看文章", "View_Article", new { id = Model.Id, articleTitle = Model.ArticleSlug }) - 排查404/400错误:
- 404通常是路由顺序不对,或者参数不匹配(比如id不是数字但你加了约束);
- 400.1错误大概率是路由参数缺失或类型不匹配,检查默认值是否设置正确。
内容的提问来源于stack exchange,提问作者dave317
相关产品推荐
相关产品推荐

