首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在asp网络内核3.1中使用RouteDataRequestCultureProvider

在asp网络内核3.1中使用RouteDataRequestCultureProvider
EN

Stack Overflow用户
提问于 2019-12-10 13:08:53
回答 2查看 2.9K关注 0票数 7

从核心2.2升级到3.1,我无法让RouteDataRequestCultureProvider完全工作。

路由工作,但剃刀标记助手忽略了使用区域性的区域性和路由属性。

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

代码语言:javascript
运行
复制
public class StaticPageController : Controller
{
    [Route("{culture:culture}/cookies")]
    public IActionResult Cookies() => View();
}

如果我转到url https://localhost:5002/en/cookies,操作将被正确地路由到。但是在剃须刀里,如果我用这样的帮手:

代码语言:javascript
运行
复制
<a asp-controller="StaticPage" asp-action="Cookies">Cookie information</a>

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

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

路由数据字典正确地包含一个区域性条目,但剃刀助手不再使用它,并且默认为默认路由模式:

代码语言:javascript
运行
复制
app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapControllerRoute("default", "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
        });

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

编辑:

我现在知道区域性不会从路由值传递到url生成器,因为它被认为是环境的,并且环境值不再包含在核心2.2中。

当前请求的路由数据值在ASP.NET Core2.1和更早版本中被视为环境值

我可以通过这样显式地指定区域性来解决这个问题:

代码语言:javascript
运行
复制
 <a 
    asp-controller="StaticPage" 
    asp-action="Cookies" asp-route- 
    culture="@Context.Request.RouteValues["culture"]">
       Cookies
 </a>

为每个页面上的每个链接指定这个将是非常乏味的。

是否有一种方法可以覆盖 标签助手 以自动将当前区域性包含在路由值中?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-11 10:15:07

因此,我最终解决了这个问题,重写了锚标记助手的工作方式,并确保它总是从路由传入区域性。

这是自定义标记助手:

代码语言:javascript
运行
复制
[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中添加您自己的锚标记。

代码语言:javascript
运行
复制
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Your.Assembly.Namespace //assembly name containing class above

一些有用的链接:

票数 8
EN

Stack Overflow用户

发布于 2020-01-04 07:46:16

@英雄主义者,你的解决方案拯救了我的生命:)

只是它的一个简化版本:

代码语言:javascript
运行
复制
//...
public CultureAnchorTagHelper(IHtmlGenerator generator) : base(generator)
{
    RouteValues["culture"] = CultureInfo.CurrentCulture.Name;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59267971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档