如何在 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

如何去掉问号和后面的参数。

【问题讨论】:

我完全不推荐使用&lt;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(例如&lt;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 本地化器

net core 3.1 MVC如何返回JSONP

我应该如何保护我的 Web 应用程序(ASP.Net Core 3.1 MVC)?

在 2 个控制器 ASP.NET Core 3.1 MVC 之间传递 ID

如何将两个数组作为 POST 请求参数从 AJAX 发送到 MVC 控制器(ASP .NET Core 3.1 剃须刀)?