Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“如何自动消除重复数据”;“规范链接”;ASP.NET Core 3.1 C#中的重定向程序?_C#_Asp.net Core - Fatal编程技术网

“如何自动消除重复数据”;“规范链接”;ASP.NET Core 3.1 C#中的重定向程序?

“如何自动消除重复数据”;“规范链接”;ASP.NET Core 3.1 C#中的重定向程序?,c#,asp.net-core,C#,Asp.net Core,对于我的ASP.NET Core 3.1 C#应用程序中的每个网页,我希望自动生成一个规范链接,用于SEO目的 目前(POC阶段),我在每个控制器操作函数中都有以下代码片段: uriactualurl=newuri($“{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}{HttpContext.Request.QueryString}”); RouteValueDictionary

对于我的ASP.NET Core 3.1 C#应用程序中的每个网页,我希望自动生成一个规范链接,用于SEO目的

目前(POC阶段),我在每个控制器操作函数中都有以下代码片段:

uriactualurl=newuri($“{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}{HttpContext.Request.QueryString}”);
RouteValueDictionary值=RouteData.values;
移除(“控制器”);
价值观。删除(“行动”);
foreach(HttpContext.Request.Query中的var q)
添加(q.Key,q.Value);
//这里有更多的路由/查询参数“fixes”。
Uri canonicalUrl=新Uri(Url.ActionLink(值:值));
如果(!canonicalUrl.Equals(actualUrl))
返回RedirectPermanentPreserveMethod(canonicalUrl.ToString());
此代码段首先使用当前实际URL构建一个
Uri
。然后它可能“修复”一些重要的路由/查询参数(如下所示)。最后,它将实际uri与所需uri进行比较,并在实际uri与所需uri不同(区分大小写)时重定向到所需uri

RouteData.Values[“子页面”]=“数字内容”;
此过程使web应用程序能够为以下示例url生成正确的规范url()

然而,POC是大量代码的重复,因此本身并不可取

我的第一个想法是使用中间件。但是,使用中间件,操作控制器无法“修复”路由/查询参数,这些参数超出常规路由构造的范围(如大多数ASP.NET示例中显示的“id”路由参数)。例如,
ActionLink
能够为控制器和操作生成正确的区分大小写的url段塞,但不能处理(“修复”)其他路由/查询参数

我的第二个想法是使用泛型类,但在那里我失去了上下文

最好的解决方案是单个(void)函数调用,它可以放在实际操作繁重的处理之前(在处理数据和生成输出之前放在操作控制器内部)


如何消除此“自动规范重定向器”代码中的重复数据?

这可能不是最佳解决方案,我只是根据您提供的代码修改了案例:

 [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());
        }
    }
用法 如果您使用视图模型中的名称来生成URL,如
example.com/some category/some product
,那么我将使用本文中的帮助程序根据模型名称生成一个串中的slug(在我的示例中,它在模型创建时保存到db) 然后使用自定义路线:

  endpoints.MapControllerRoute(
                    name: "category",
                    pattern: "{Category}/{Product}",
                    defaults: new { controller = "Product", action = "Index" });
此模式从路由中省略了操作和控制器名称(我更喜欢这样) 并提供如下内容
example.com/some category/some product
,在您的操作中,您只需将模型的slug与用户提供的路由段(使用路由约束)进行比较,如下所示:

 public async Task<IActionResult> Index([FromRoute,Required] Category,[FromRoute,Required] Product)
  return RedirectToRoutePermanent("category", new { Product = Product.Slug, Category = Product.Category.Slug });

希望这有帮助。

将其作为控制器属性编写如何?如果您的路由依赖于视图模型名称,并且在这种情况下,带有自动生成的slug的自定义路由将有助于您在不匹配时与路由重定向进行字符串比较(这是iam所做的)@HMZ请添加一个aswer,您的建议似乎很有趣,可能与您的设计不匹配,但MediatR和MediatR可以帮助满足您的需求,这一切都是最好的
  return RedirectToRoutePermanent("category", new { Product = Product.Slug, Category = Product.Category.Slug });