如何让Url.Action生成无ID的article/slug格式URL(保留带ID的Action)
解决Url.Action总是匹配带ID的Action重载问题
你的问题其实是因为当前页面的路由数据里包含了id参数(来自分类页面的URL http://localhost/category/6/category-name),ASP.NET Core的Url.Action会自动从当前上下文的路由数据中填充未显式指定的参数,所以即使你没在参数里写id,它也会把当前的6带进去,导致匹配了带id的ArticleDetails重载。
下面给你几种不用删除带ID的Action就能解决的方法:
方法1:显式传递id=null覆盖当前路由数据
在调用Url.Action时,明确指定id为null,这样就会覆盖当前路由里的id值,让路由系统匹配只带slug的Action重载:
@Url.Action("ArticleDetails", "Information", new { slug = article.Slug, id = (int?)null })
这里要注意把id声明为可空类型,避免编译报错。
方法2:给无ID的Action路由设置名称,用路由名生成URL
先给第二个ArticleDetailsAction添加路由名称:
[HttpGet("article/{slug}", Name = "ArticleBySlug")] public IActionResult ArticleDetails(string slug) { // 你的业务代码 return View(data); }
然后在Razor页面里用Url.RouteUrl指定这个路由名称,直接生成对应格式的URL:
@Url.RouteUrl("ArticleBySlug", new { slug = article.Slug })
这种方法更直接,通过路由名称精准匹配你想要的路由规则,不会受到当前路由数据的干扰。
方法3:使用LinkGenerator生成URL
你也可以在Razor页面中注入LinkGenerator,通过它来生成指定Action的URL,同样需要确保排除id参数:
@inject LinkGenerator LinkGenerator @LinkGenerator.GetPathByAction("ArticleDetails", "Information", values: new { slug = article.Slug })
这种方式和Url.Action类似,但可以更灵活地控制参数传递。
这几种方法都能帮你生成article/article-slug格式的URL,同时保留带ID的Action重载。
内容的提问来源于stack exchange,提问作者Endri
相关产品推荐
相关产品推荐

