如何在 mvc core 3.1 中显示 seo 友好的 url?
Posted
技术标签:
【中文标题】如何在 mvc core 3.1 中显示 seo 友好的 url?【英文标题】:How to show seo friendly url in mvc core 3.1? 【发布时间】:2021-12-13 08:31:12 【问题描述】:我正在开发一个 mvc core 3.1 应用程序。 SEO 要求是用主站点而不是完整的 url 显示产品名称。
我原来的网址是
www.abc.com/Fashion/ProductDetail?productId=5088&productName=AliviaBlack&brandId=3
要求是
www.abc.com/alivia-black
我尝试过使用属性路由来跟踪
endpoints.MapControllerRoute(
name: "SpecificRoute",
pattern: "/productName",
defaults: new controller = "Fashion", action = "ProductDetail", id= "productId" );
在查看页面中
<a asp-route-productId="@product.ProductId"
asp-route-productName="@Common.FilterURL(product.ProductName)"
asp-route-brandId="@product.FashionBrand.FashionBrandId" asp-route="SpecificRoute">
结果是
www.abc.com/alivia-black?productId=5223&brandId=4
如何去掉问号和后面的参数。
【问题讨论】:
我完全不推荐使用<a asp-route-...
,因为它太不灵活了。而是使用您自己的自定义 URL 生成方法。并且您仍然应该包含数字 productId
值(作为路由参数,而不是查询字符串参数) - 否则重命名产品时链接会中断。
你应该先阅读这个:w3.org/2011/gld/wiki/223_Best_Practices_URI_Construction
您使用的是 ASP.NET MVC 还是 ASP.NET Core?您已将您的问题标记为两者,这是错误的。
@Dai 感谢您的评论。是否可以在 get 请求中隐藏 productId 和 brandId 或者我必须将其更改为通过 ajax 发布请求?
我认为您没有阅读我发布的链接。您需要在您的 URI 中包含 productId
(但它不需要是查询参数)。如果您不这样做,那么您将遇到链接断开的无穷无尽的问题。另外,我怀疑您不熟悉 HTTP 的工作原理,因为您似乎误解了 POST 请求的确切工作原理。
【参考方案1】:
首先,URI 需要具有弹性。您说您当前的要求是拥有这样的 URI:
www.abc.com/alivia-black
即:
host/productName
这是一个非常糟糕的 URI 模板,因为:
它不能唯一地识别产品(因为您可以拥有多个同名产品)。 如果您重命名产品或替换同名产品,它将破坏来自外部网站的现有链接。这在任何产品数据库中经常发生。 因为您将productName
放在 URI 结构的“根”中,这意味着除了查看产品之外,处理其他任何事情要困难得多(例如,您如何拥有 /contact-us
页面?如果您有一个名为 contact-us
的产品怎么办?)
我强调在 URI 中包含被请求实体的不可变键(在本例中为您的 productId
值)并将其用作主要引用非常重要,因此 productName
可以是处理传入的 HTTP 请求时忽略。这就是 *** 和 Amazon 的 URI 的工作方式(您可以在 *** 的 question-id 之后剪掉文本,它仍然可以工作:例如
https://***.com/questions/69748993/how-to-show-seo-friendly-url-in-mvc-core-3-1
https://***.com/questions/69748993
I strongly recommend you read this article on the W3.org's website all about designing good URIs,以及other guidance from that group's homepage。
我建议你使用更好的 URI 模板,比如这个:
host/products/productId/productName
这会给你一个这样的 URI:
abc.com/products/5088/alivablack
在 ASP.NET MVC(和 ASP.NET Core)中处理这样的链接很简单,只需在控制器操作上设置路由模板:
[Route( "/products/productId:int/productName?" )]
public async Task<IActionResult> ShowProduct( Int32 productId, String? productName = null )
// Use `productId` to lookup the product.
// Disregard `productName` unless you want to use it as a fallback to search your database if `productId` doesn't work.
至于生成 URI,我建议反对使用TagHelpers(例如<a asp-route-
),因为它们无法让您充分控制URI 的呈现方式,相反,您可以定义一个UrlHelper
扩展方法(确保您将@import
命名空间添加到您的.cshtml
页面(或将其添加到ViewStart
):
public static class MyUrls
public static String ShowProduct( this IUrlHelper u, Int32 productId, String productName )
const String ACTION_NAME = nameof(ProductsController.ShowProduct);
const String CONTROLLER_NAME = "Products"; // Unfortunately we can't use `nameof` here due to the "Controller" suffix in the type-name.
String url = u.Action( action: ACTION_NAME, controller: CONTROLLER_NAME, values: new productId = productId, productName = productName );
return url;
那么你可以这样使用它:
<a href="@Urls.ShowProduct( 5088, "aliviablack" )">View AliviaBlack</a>
您也可以让ShowProduct
直接接受您的Product
对象之一,然后将值传递给另一个接受标量的重载(上面定义):
public static String ShowProduct( this IUrlHelper u, Product product )
String url = ShowProduct( u, productId: product.ProductId, productName: product.ProductName );
return url;
然后你可以像这样使用它(假设product
在范围内):
<a href="@Urls.ShowProduct( product )">@product.ProductName</a>
【讨论】:
以上是关于如何在 mvc core 3.1 中显示 seo 友好的 url?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 在 ASP.NET Core 3.1 MVC 中使用会话变量
在 ASP.net core mvc 3.1 中的 HtmlHelper 扩展方法中使用 DataAnnotation 本地化器
我应该如何保护我的 Web 应用程序(ASP.Net Core 3.1 MVC)?
在 2 个控制器 ASP.NET Core 3.1 MVC 之间传递 ID
如何将两个数组作为 POST 请求参数从 AJAX 发送到 MVC 控制器(ASP .NET Core 3.1 剃须刀)?