从核心2.2升级到3.1,我无法让RouteDataRequestCultureProvider完全工作。
路由工作,但剃刀标记助手忽略了使用区域性的区域性和路由属性。
作为自定义路由属性的简单示例:
public class StaticPageController : Controller
{
[Route("{culture:culture}/cookies")]
public IActionResult Cookies() => View();
}
如果我转到url https://localhost:5002/en/cookies
,操作将被正确地路由到。但是在剃须刀里,如果我用这样的帮手:
<a asp-controller="StaticPage" asp-action="Cookies">Cookie information</a>
它生成的结果链接是:https://localhost:5002/en/staticpage/cookies
在核心2.2中,这正确地生成了url https://localhost:5002/en/cookies
路由数据字典正确地包含一个区域性条目,但剃刀助手不再使用它,并且默认为默认路由模式:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapControllerRoute("default", "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
});
有人知道为什么剃刀标签助手不再使用路由数据字典中的区域性了吗?
编辑:
我现在知道区域性不会从路由值传递到url生成器,因为它被认为是环境的,并且环境值不再包含在核心2.2中。
当前请求的路由数据值在ASP.NET Core2.1和更早版本中被视为环境值
我可以通过这样显式地指定区域性来解决这个问题:
<a
asp-controller="StaticPage"
asp-action="Cookies" asp-route-
culture="@Context.Request.RouteValues["culture"]">
Cookies
</a>
为每个页面上的每个链接指定这个将是非常乏味的。
是否有一种方法可以覆盖 标签助手 以自动将当前区域性包含在路由值中?
发布于 2019-12-11 10:15:07
因此,我最终解决了这个问题,重写了锚标记助手的工作方式,并确保它总是从路由传入区域性。
这是自定义标记助手:
[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
中添加您自己的锚标记。
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Your.Assembly.Namespace //assembly name containing class above
一些有用的链接:
发布于 2020-01-04 07:46:16
@英雄主义者,你的解决方案拯救了我的生命:)
只是它的一个简化版本:
//...
public CultureAnchorTagHelper(IHtmlGenerator generator) : base(generator)
{
RouteValues["culture"] = CultureInfo.CurrentCulture.Name;
}
https://stackoverflow.com/questions/59267971
复制相似问题