简体   繁体   English

如何对 ASP.NET Core 3.1 C# 中的自动“规范链接”重定向器进行重复数据删除?

[英]How to deduplicate an automatic “Canonical Link” redirector in ASP.NET Core 3.1 C#?

For every web page within my ASP.NET Core 3.1 C# application, I want to automatically generate an canonical link for SEO purposes.对于我的 ASP.NET Core 3.1 C# 应用程序中的每个 web 页面,我想为 SEO 目的自动生成规范链接。

Currently (POC phase), I have the following snippet in every controller action function:目前(POC 阶段),我在每个 controller 动作 function 中都有以下片段:

Uri actualUrl = new Uri($"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}{HttpContext.Request.QueryString}");
RouteValueDictionary values = RouteData.Values;
values.Remove("controller");
values.Remove("action");
foreach (var q in HttpContext.Request.Query)
    values.Add(q.Key, q.Value);
// Further route/query parameter "fixes" here.
Uri canonicalUrl = new Uri(Url.ActionLink(values: values));
if (!canonicalUrl.Equals(actualUrl))
    return RedirectPermanentPreserveMethod(canonicalUrl.ToString());

This snippet first builds a Uri with the current actual URL.此代码段首先使用当前实际的 URL 构建一个Uri Then it may "fixes" some important route/query parameters (as shown below).然后它可能会“修复”一些重要的路由/查询参数(如下所示)。 Finally it compares the actual uri with the desired uri, and redirects to the desired uri, when the actual uri is different compared to the desired uri (case sensitive).最后,它将实际 uri 与所需 uri 进行比较,并在实际 uri 与所需 uri 不同时重定向到所需 uri(区分大小写)。

RouteData.Values["subpage"] = "Digital-Contents";

This process enables the web application to generate the correct canonical url ( http://example.com/MyController/MyAction/Digital-Contents ) for the following sample urls.此过程使 web 应用程序能够为以下示例 URL 生成正确的规范 url( http://example.com/MyController/MyAction/Digital-Contents )。

However, the POC is a massive duplication of code, and thus not desirable itself.然而,POC 是大量的代码重复,因此本身并不理想。

My first thought was to use a middleware.我的第一个想法是使用中间件。 However, with an middleware, the action controller cannot "fix" route/query parameters, which are out-of-scope of the regular routing construct (like the "id" route parameter which is shown in most ASP.NET examples).但是,对于中间件,操作 controller 无法“修复”路由/查询参数,这些参数超出了常规路由结构的范围(如大多数 ASP.NET 示例中显示的“id”路由参数)。 Eg ActionLink is capable of producing the correct case sensitive url slugs for controller and action, but cannot process ("fix") other route/query parameters.例如, ActionLink能够为 controller 和操作生成正确的区分大小写的 url slug,但不能处理(“修复”)其他路由/查询参数。

My second thought was to use a generic class, but there I lose the context.我的第二个想法是使用通用的 class,但我失去了上下文。

The best solution would be a single (void) function call, which can be placed before the actual action heavy processing (inside the action controller before processing data and generating output).最好的解决方案是单个(无效)function 调用,它可以放置在实际操作重处理之前(在处理数据和生成输出之前的操作 controller 内部)。

How to deduplicate this "automatic canonical redirector" code?如何对这个“自动规范重定向器”代码进行重复数据删除?

This may not be the best solution, i just modified the case based on the code you provided:这可能不是最好的解决方案,我只是根据您提供的代码修改了案例:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class CanonicalUrlAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var httpContext = filterContext.HttpContext;

            Uri actualUrl = new Uri($"{httpContext.Request.Scheme}://{httpContext.Request.Host}{httpContext.Request.Path}{httpContext.Request.QueryString}");
            RouteValueDictionary values = filterContext.RouteData.Values;
            values.Remove("controller");
            values.Remove("action");
            foreach (var q in httpContext.Request.Query)
                values.Add(q.Key, q.Value);

            // Further route/query parameter "fixes" here.
            Uri canonicalUrl = new Uri(new UrlHelper(filterContext).ActionLink(values));
            if (!canonicalUrl.Equals(actualUrl))
                filterContext.Result = new LocalRedirectResult(canonicalUrl.ToString());
        }
    }

Usage用法

 [CanonicalUrl]
 public class HomeController : Controller {

}

If you're using names from view models to generate urls like example.com/some-category/some-product then i would use the helper in this Link to generate a slug in kebab case based on the model name (in my case its saved to db on model creation) then with a custom route:如果您使用视图模型中的名称来生成诸如example.com/some-category/some-product之类的 URL,那么我将使用此链接中的帮助程序根据 model 名称(在我的情况下为在创建 model 时保存到 db)然后使用自定义路由:

  endpoints.MapControllerRoute(
                    name: "category",
                    pattern: "{Category}/{Product}",
                    defaults: new { controller = "Product", action = "Index" });

This pattern omits the action and controller names from route (which i prefer) and gives you something like this example.com/some-category/some-product and in your action you just compare the model's slug with the route segment that is provided by the user (using the route contraint) like this:这种模式省略了动作和 controller 来自 route 的名称(我更喜欢),并为您提供类似example.com/some-category/some-product的内容,在您的操作中,您只需将模型的 slug 与提供的路线段进行比较用户(使用路由约束)如下:

 public async Task<IActionResult> Index([FromRoute,Required] Category,[FromRoute,Required] Product)

and you do a route redirect on mismatch like this:并且您对不匹配进行路由重定向,如下所示:

  return RedirectToRoutePermanent("category", new { Product = Product.Slug, Category = Product.Category.Slug });

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 C# 在 ASP.NET Core 3.1 MVC 中使用会话变量 - How to use session variables in ASP.NET Core 3.1 MVC using C# 如何使用 ASP.NET Core 3.1 MVC 中的 ViewModel 与 JavaScript 和 C# 动态添加到列表 - How to dynamically add to list with ViewModel in ASP.NET Core 3.1 MVC with JavaScript and C# 如何使用 C# ASP.Net Core 3.1 在服务器端检查 cookie 选项 - How to check cookie options on server side using C# ASP.Net Core 3.1 如何在 asp.net 核心 3.1 中将文本用作 c# 代码? - How to use text as a c# code in asp.net core 3.1? 一些 C# 9 功能在将 Asp.Net Core 3.1 应用程序升级到 .Net 5 后不可用 - Some C# 9 features not available after upgrading Asp.Net Core 3.1 app to .Net 5 ASP.NET Core React项目模板-如何链接到C#后端 - ASP.NET Core React project template - how to link to C# backend C# ASP.NET WebApi (2/Core 3.1) 大数的 Json 序列化问题 - C# ASP.NET WebApi (2/Core 3.1) Problem with Json serialization of big numbers Static 文件未通过 IIS 提供,但通过本地主机提供 - ASP.NET 核心 3.1 MVC 和 ZD7EFAZDA19FBE7D3972FDB602422 - Static file not served through IIS but serving through localhost - ASP.NET Core 3.1 MVC & C# Asp.Net Core 3.1 Cookies 未附加 Razor 页 C# - Asp.Net Core 3.1 Cookies not appended Razor Pages C# 如何在 ASP.NET Core 3.1 中使用 protobuf-net 3 - How to use protobuf-net 3 with ASP.NET Core 3.1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM