【问题标题】:How to show seo friendly url in mvc core 3.1?如何在 mvc core 3.1 中显示 seo 友好的 url?
【发布时间】: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 值(作为路由参数,而不是查询字符串参数) - 否则重命名产品时链接会中断。
  • 您使用的是 ASP.NET MVC 还是 ASP.NET Core?您已将您的问题标记为两者,这是错误的。
  • @Dai 感谢您的评论。是否可以在 get 请求中隐藏 productId 和 brandId 或者我必须将其更改为通过 ajax 发布请求?
  • 我认为您没有阅读我发布的链接。您需要在您的 URI 中包含 productId(但它不需要是查询参数)。如果您不这样做,那么您将遇到链接断开的无穷无尽的问题。另外,我怀疑您不熟悉 HTTP 的工作原理,因为您似乎误解了 POST 请求的确切工作原理。

标签: asp.net-mvc asp.net-mvc-5 asp.net-core-3.1


【解决方案1】:

首先,URI 需要具有弹性。您说您当前的要求是拥有这样的 URI:

www.abc.com/alivia-black

即:

{host}/{productName}

这是一个非常糟糕的 URI 模板,因为:

  • 它不能唯一地识别产品(因为您可以拥有多个同名产品)。
  • 如果您重命名产品或替换同名产品,它将破坏来自外部网站的现有链接。这在任何产品数据库中经常发生
  • 因为您将 {productName} 放在 URI 结构的“根”中,这意味着除了查看产品之外,处理其他任何事情要困难得多(例如,您如何拥有 /contact-us页面?如果您有一个名为 contact-us 的产品怎么办?)

我强调在 URI 中包含被请求实体的不可变键(在本例中为您的 productId 值)并将其用作主要引用非常重要,因此 productName 可以是处理传入的 HTTP 请求时忽略。这就是 StackOverflow 和 Amazon 的 URI 的工作方式(您可以在 StackOverflow 的 question-id 之后剪掉文本,它仍然可以工作:例如

https://stackoverflow.com/questions/69748993/how-to-show-seo-friendly-url-in-mvc-core-3-1

https://stackoverflow.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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 2013-01-20
    相关资源
    最近更新 更多