如何在MVC Core 3.1中实现SEO友好的URL地址
解决方案
问题根源
你的路由模板/{productName}仅声明了productName一个路由占位符,生成链接时传入的productId、brandId没有匹配到路由模板中的参数,ASP.NET Core路由系统会自动将未匹配的额外参数转为查询字符串拼接在URL末尾,就出现了你现在看到的结果。
具体解决步骤
根据你的业务需求分两种实现方案:
方案一:可通过商品Slug(即转换后的productName)唯一查询商品信息
这是最推荐的SEO友好实现方案,操作如下:
- 调整路由配置,删除无用的默认id参数,同时注意将该路由放在所有路由规则的最上方,避免被其他路由优先匹配:
endpoints.MapControllerRoute( name: "SpecificRoute", pattern: "{productName}", defaults: new { controller = "Fashion", action = "ProductDetail" }); // 原有其他路由放在这条路由之后
如果偏好使用特性路由实现,可直接在ProductDetail动作上添加路由特性,无需配置全局路由规则:
[Route("{productName}", Name = "SpecificRoute")] public IActionResult ProductDetail(string productName) { // 业务逻辑 }
- 修改视图链接代码,删除多余的
productId、brandId传参:
<a asp-route-productName="@Common.FilterURL(product.ProductName)" asp-route="SpecificRoute">
- 调整
Fashion控制器下ProductDetail动作方法的参数,仅保留productName,在业务逻辑中通过productName查询对应的商品、品牌信息即可。
注意:单参数顶级路由容易和系统其他控制器的路由冲突,建议添加自定义路由约束,验证当前
productName是否为真实存在的商品Slug,验证通过才匹配该路由,否则继续匹配后续其他路由规则。
方案二:必须依赖productId、brandId查询商品,不希望参数出现在URL中
如果你的系统存在重名商品,无法仅通过Slug查询唯一商品,可通过缓存映射的方式实现:
- 生成商品链接时,将
productSlug、productId、brandId的映射关系存入内存缓存/分布式缓存,设置较长的过期时间 - 路由配置和视图传参参考方案一配置,URL仅保留
productName - 在
ProductDetail动作中,拿到productName后先去缓存中查询对应的productId和brandId,再执行后续业务逻辑即可。
内容的提问来源于stack exchange,提问作者mck
相关产品推荐
相关产品推荐

