用RouteDataRequestCultureProvider

用RouteDataRequestCultureProvider

本文介绍了在ASP Net Core 3.1中使用RouteDataRequestCultureProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从核心2.2升级到3.1后,RouteDataRequestCultureProvider无法完全正常工作.

Having upgraded from core 2.2 to 3.1 I cannot get RouteDataRequestCultureProvider working fully.

路由工作正常,但剃刀标签助手却忽略了文化,而忽略了使用文化的路线属性.

Routing works but razor tag helpers are ignoring the culture and route attributes that use culture.

作为自定义路由属性的简单示例:

As simple example of custom route attribute:

public class StaticPageController : Controller
{
    [Route("{culture:culture}/cookies")]
    public IActionResult Cookies() => View();
}

如果我转到url https://localhost:5002/en/cookies,则该操作将正确路由.但是在剃须刀中,如果我使用像这样的助手:

If I go to the url https://localhost:5002/en/cookies the action is routed to correctly.However in razor, if I use a helper like this:

<a asp-controller="StaticPage" asp-action="Cookies">Cookie information</a>

它生成的结果链接为:https://localhost:5002/en/staticpage/cookies

The resulting link it generates is: https://localhost:5002/en/staticpage/cookies

在核心2.2中,这正确生成了URL https://localhost:5002/en/cookies

In core 2.2 this was correctly generating the url https://localhost:5002/en/cookies

路线数据字典正确包含用于文化的条目,但剃刀助手不再使用它,并且默认为默认路线模式:

The route data dictionary correctly contains an entry for culture but the razor helper is no longer using it and is defaulting to the default route pattern:

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapControllerRoute("default", "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
        });

有人知道为什么剃刀标签助手不再使用路线数据字典中的区域性吗?

Does anyone know why the razor tag helper is no longer using the culture from the route data dictionary?

我现在知道文化并没有从路由值传递到url生成器,因为它被认为是环境值,并且从核心2.2开始不再包含环境值.

I now know that culture is not being passed from the route values into the url generator because it is considered ambient, and ambient values are no longer included as of core 2.2.

我可以通过明确指定区域性来解决此问题:

I can fix this by specifying the culture explicitly thus:

 <a
    asp-controller="StaticPage"
    asp-action="Cookies" asp-route-
    culture="@Context.Request.RouteValues["culture"]">
       Cookies
 </a>

为每个页面上的每个链接进行指定将非常繁琐.

Specifying this for every link on every page is going to be very tedious.

是否可以覆盖标记助手可以自动将当前区域性包括在路线值中?

Is there a way to override the tag helper to automatically include the current culture in the route values?

推荐答案

因此,我最终通过覆盖定位标记帮助程序的工作方式并确保它始终从路线中传出来来解决了这个问题.

So I ended up fixing this problem by overriding how the anchor tag helper works and making sure it always passes in the culture from the route.

这是自定义标签帮助程序:

This is the custom tag helper:

[HtmlTargetElement("a", Attributes = ActionAttributeName)]
[HtmlTargetElement("a", Attributes = ControllerAttributeName)]
[HtmlTargetElement("a", Attributes = AreaAttributeName)]
[HtmlTargetElement("a", Attributes = PageAttributeName)]
[HtmlTargetElement("a", Attributes = PageHandlerAttributeName)]
[HtmlTargetElement("a", Attributes = FragmentAttributeName)]
[HtmlTargetElement("a", Attributes = HostAttributeName)]
[HtmlTargetElement("a", Attributes = ProtocolAttributeName)]
[HtmlTargetElement("a", Attributes = RouteAttributeName)]
[HtmlTargetElement("a", Attributes = RouteValuesDictionaryName)]
[HtmlTargetElement("a", Attributes = RouteValuesPrefix + "*")]
public class CultureAnchorTagHelper : AnchorTagHelper
{
    private const string ActionAttributeName = "asp-action";
    private const string ControllerAttributeName = "asp-controller";
    private const string AreaAttributeName = "asp-area";
    private const string PageAttributeName = "asp-page";
    private const string PageHandlerAttributeName = "asp-page-handler";
    private const string FragmentAttributeName = "asp-fragment";
    private const string HostAttributeName = "asp-host";
    private const string ProtocolAttributeName = "asp-protocol";
    private const string RouteAttributeName = "asp-route";
    private const string RouteValuesDictionaryName = "asp-all-route-data";
    private const string RouteValuesPrefix = "asp-route-";


    public CultureAnchorTagHelper(IHtmlGenerator generator, IHttpContextAccessor contextAccessor) : base(generator)
    {
        var culture = contextAccessor.HttpContext.Request.RouteValues["culture"]?.ToString() ?? "en";
        RouteValues["culture"] = culture;
    }
}

要使用它,您需要删除默认的锚标记帮助器,然后在_ViewImports.cshtml中添加自己的帮助器:

To use it you need to remove the default anchor tag helper and add your own in _ViewImports.cshtml:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Your.Assembly.Namespace //assembly name containing class above

一些有用的链接:

  • anchor tag source code
  • tag helpers
  • extending tag helpers

这篇关于在ASP Net Core 3.1中使用RouteDataRequestCultureProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 00:22