如何去除.NET Core MVC URL中多余的“Home”与“Index”组件?
我来帮你解决这个.NET Core 2.0 MVC(以及新版ASP.NET MVC模板)URL生成不符合预期的问题。这个差异主要源于新旧版本路由系统处理默认值的逻辑变化,下面我会详细解释原因并给出几种可行的解决方案:
为什么会出现这个问题?
旧版ASP.NET MVC的URL生成逻辑会自动省略路由中配置的默认控制器(比如Home)和默认动作(比如Index),哪怕你显式指定了这些值。但.NET Core MVC(以及更新后的传统ASP.NET MVC模板)的路由系统更严谨——默认情况下,如果你在生成URL时明确指定了默认控制器/动作,它会把这些值保留在URL里,就出现了你看到的/Home/About(本该是/About)、/Manage/Index(本该是/Manage)的情况。
解决方案
1. 用属性路由直接定义URL(最推荐)
这种方式最直观,完全可控,直接给控制器或动作加上[Route]属性来指定你想要的URL:
比如Home控制器的About动作:
public class HomeController : Controller { public IActionResult Index() => View(); // 直接指定URL为/About [Route("About")] public IActionResult About() => View(); }
Manage控制器的Index动作:
public class ManageController : Controller { // 指定URL为/Manage,替代默认的/Manage/Index [Route("Manage")] public IActionResult Index() => View(); }
这样不管在哪里生成链接,都会得到你预期的简洁URL。
2. 调整默认路由配置,让系统自动省略默认值
如果你想继续使用默认路由,可以通过配置让路由系统在生成URL时自动忽略默认的控制器和动作:
.NET Core 2.0+的配置方法
在Startup.cs的Configure方法里,修改默认路由的配置,添加SuppressLinkGenerationForDefaultValues = true:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}", dataTokens: new { SuppressLinkGenerationForDefaultValues = true } ); });
开启这个选项后,当你生成默认控制器/动作的URL时,系统会自动省略这些部分。
另外,如果你需要手动生成URL,也可以通过移除路由值里的默认项来实现:
// 生成/About而不是/Home/About var routeValues = new RouteValueDictionary(new { action = "About", controller = "Home" }); routeValues.Remove("controller"); // 移除默认控制器值 var url = Url.RouteUrl(routeValues);
传统ASP.NET MVC的调整方法
在RouteConfig.cs里确保路由配置正确,然后生成URL时尽量不指定默认控制器:
// 生成Home/About的URL时,直接调用(默认使用当前上下文的控制器,若当前在Home控制器中则生成/About) Url.Action("About"); // 如果在其他控制器中,手动构建路由值时不包含默认控制器 var routeValues = new RouteValueDictionary { { "action", "About" } }; var url = Url.RouteUrl(routeValues);
3. 使用Tag Helper时的小技巧
如果你用<a>标签的Tag Helper生成链接,默认指定asp-controller="Home"会生成/Home/About。要得到/About,可以去掉asp-controller="Home"(因为Home是默认控制器),或者添加asp-route-suppress-defaults="true":
<a asp-action="About" asp-route-suppress-defaults="true">About</a>
这样就能生成你想要的简洁链接了。
内容的提问来源于stack exchange,提问作者Amethi

