Action.RouteLink不为文化采用前缀url

接下来是关于创建文化和在所有URL中添加前缀文化参数的帖子,如下所示

ASP.NET MVC 5 culture in route and url

我正在制作杂志(阿拉伯语和英语)和主页链接如下:localhost:1025 / Blog / Home //默认阿拉伯语localhost:1025 / en / blog / home // for English

我在Controller'blog'下添加了一个名为'tag'的新动作来显示特定标签的帖子 . 已添加在routeConfig代码中,如下所示:

routes.MapRoute(
          name: "BlogListTag",
          url: "{controller}/{action}/{Name}/{page}/{pageNo}",
          defaults: new { controller = "Blog", action = "Tag", Name = UrlParameter.Optional, pageNo = UrlParameter.Optional, page = UrlParameter.Optional }

      );

所以这必须以文化约束参数作为前缀,因为代码适用于:

routes.LowercaseUrls = true;
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        // Call to register your localized and default attribute routes
        routes.MapLocalizedMvcAttributeRoutes(
            urlPrefix: "{culture}/",
             defaults: new { culture = "ar" },
            constraints: new { culture = new CultureConstraint(defaultCulture: "ar", pattern: "[a-z]{2}") }
        );

现在在Home动作我在Partial视图中列出文章链接所以每篇文章都有一些标签页面的链接 . 我在局部视图中使用了这段代码

@Html.ActionLink(@t.Name,"Tag",new { Name = t.NameEn.AddDashes() },new { title= Resources.Resource.Tag+":"+ @t.Name })

当我浏览阿拉伯语时,我在浏览器中检查时得到链接:

localhost:1025 / blog / tag?Name = XYZ //阿拉伯语

当我用英语切换到主页时

localhost:1025 / en / blog / tag?Name = XYZ //英文

它工作正常,它捕获文化,并包含在链接中 . 但我不想显示与查询字符串的链接

这是问题,当我使用Html.RouteLink而不是ActionLink替换代码时,它遵循RouteConfig的路由,但不采用任何前缀文化 . 所以这是链接代码行:

@Html.RouteLink(@t.Name, "BlogListTag", 
new { Name = t.NameEn.AddDashes(),action="tag" },
new { title= Resources.Resource.Tag+":"+ @t.Name })
//Note: I included action because it doesn't work without it

阿拉伯语和英语页面中的结果链接

localhost:1025 / blog / tag / XYZ // in Arabic localhost:1025 / blog / tag / XYZ // in English'注意:没有捕获文化前缀

我最后的尝试是将文化作为参数包括在内,只有当文化是恩时

@Html.RouteLink(@t.Name, "BlogListTag", 
new { Name = t.NameEn.AddDashes(),action="tag",culture="en" },
new { title= Resources.Resource.Tag+":"+ @t.Name })
//Note: I included action because it doesn't work without it
//Note: this is only inside the if statement to check the culture as English

它导致英文页面中的链接如下:

localhost:1025 / blog / tag / XYZ?culture = en // in English'注意:QueryString

我想要的就是这样:

localhost:1025 / blog / tag / XYZ // in Arabic'这个已经在阿拉伯语localhost:1025 / en / blog / tag / XYZ // in English

我想要的是RouteLink通过捕获阿拉伯语和英语的前缀文化来工作,而不试图将文化作为参数包含在内,并且没有在链接中看到任何查询字符串

感谢您的回复

回答(1)

2 years ago

这个设置有几个问题 . 您尚未设置接受文化的网址 . URL中必须有一些变量来告诉它您要查看哪种文化 . 您还有多个 UrlParameter.Optional ,这是不允许的(或者URL无法正确构建) . 每条路线只能有一个 UrlParameter.Optional 参数 .

第三个潜在问题是,如果您的网站中有其他路线,则无法正常工作 . 我在这里展示了使用文字段的示例,但请注意有many ways to constrain a route并且路由排序非常重要,因为第一场比赛总是获胜 .

// Localized route
routes.MapRoute(
      name: "BlogListTagWithPageLocalized",
      url: "{culture}/Blog/{action}/{Name}/{page}/{pageNo}",
      defaults: new { controller = "Blog", pageNo = UrlParameter.Optional },
      constraints: new { culture = new CultureConstraint(defaultCulture: "ar", pattern: "[a-z]{2}") }
);  

// Default culture route
routes.MapRoute(
      name: "BlogListTagWithPage",
      url: "Blog/{action}/{Name}/{page}/{pageNo}",
      defaults: new { culture = "ar", controller = "Blog", pageNo = UrlParameter.Optional }
);

// Localized route
routes.MapRoute(
      name: "BlogListTagLocalized",
      url: "{culture}/Blog/{action}/{Name}",
      defaults: new { controller = "Blog", Name = UrlParameter.Optional },
      constraints: new { culture = new CultureConstraint(defaultCulture: "ar", pattern: "[a-z]{2}") }
);

// Default culture route
routes.MapRoute(
      name: "BlogListTag",
      url: "Blog/{action}/{Name}",
      defaults: new { culture = "ar", controller = "Blog", Name = UrlParameter.Optional }
);

此外,如果为这样的单个页面设置多个路径(您需要进行本地化),则不能将 RouteLink 与名称一起使用 . 您 must 排除路径名称,或者使用 ActionLink 构建URL,以便可以匹配本地化路由或非本地化路由 .

@Html.RouteLink(@t.Name, /*"BlogListTag", <-- Don't include this */
    new { Name = t.NameEn.AddDashes(),action="tag" },
    new { title= Resources.Resource.Tag+":"+ @t.Name })

请注意,如果您希望将您的网址翻译成不同的语言,您链接的解决方案将无效(至少在没有一些修改的情况下) . 但是,有一个可能适合您的开源项目RouteLocalization(我还没试过) .

只有在使用属性路由并且希望属性路由已本地化时,才需要调用routes.MapLocalizedMvcAttributeRoutes() .