“如何自动消除重复数据”;“规范链接”;ASP.NET Core 3.1 C#中的重定向程序?
对于我的ASP.NET Core 3.1 C#应用程序中的每个网页,我希望自动生成一个规范链接,用于SEO目的 目前(POC阶段),我在每个控制器操作函数中都有以下代码片段:“如何自动消除重复数据”;“规范链接”;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
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()
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 });