从核心 2.2 升级到 3.1 后,我无法让 RouteDataRequestCultureProvider 充分工作。
路由有效,但 Razor 标签助手忽略区域性和使用区域性的路由属性。
作为自定义路由属性的简单示例:
public class StaticPageController : Controller
{
[Route("{culture:culture}/cookies")]
public IActionResult Cookies() => View();
}
如果我转到 URL https://localhost:5002/en/cookies
操作将正确路由到。
但是在 Razor 中,如果我使用这样的助手:
<a asp-controller="StaticPage" asp-action="Cookies">Cookie information</a>
它生成的链接是:https://localhost:5002/en/staticpage/cookies
在 core 2.2 中,这正确生成了 url https://localhost:5002/en/cookies
路由数据字典正确包含区域性条目,但 razor 助手不再使用它,并且默认为默认路由模式:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapControllerRoute("default", "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
});
有谁知道为什么 Razor 标签助手不再使用路线数据字典中的区域性?
编辑:
我现在知道区域性不会从路由值传递到 URL 生成器,因为它被视为环境变量,并且从核心 2.2 开始不再包含环境变量。
Route Data values for the current request are considered ambient values in ASP.NET Core 2.1 and earlier
我可以通过明确指定文化来解决这个问题:
<a
asp-controller="StaticPage"
asp-action="Cookies" asp-route-
culture="@Context.Request.RouteValues["culture"]">
Cookies
</a>
为每个页面上的每个链接指定这一点将非常乏味。
有没有办法覆盖 tag helper自动在路由值中包含当前文化?
最佳答案
因此,我最终通过重写 anchor 标记助手的工作方式并确保它始终从路线传递文化来解决这个问题。
这是自定义标签助手:
[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;
}
}
要使用它,您需要删除默认的 anchor 标记帮助程序并在 _ViewImports.cshtml
中添加您自己的 anchor 标记帮助程序:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Your.Assembly.Namespace //assembly name containing class above
一些有用的链接:
关于c# - 在asp net core 3.1中使用RouteDataRequestCultureProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59267971/