asp.net 为自定义路由生成URL以在RouteValues中包含用户区域性时遇到问题

lhcgjxsq  于 2023-02-01  发布在  .NET
关注(0)|答案(1)|浏览(151)

我正在尝试创建一个自定义路由,它将包括路由中的用户文化(RouteValues)。使用默认路由约定一切正常。
我有以下控制器:

public class HomeController : Controller
    {
        public HomeController()
        {
        }

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }
    }

我相信我已经在应用程序中正确配置了本地化,如下所示:

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<RequestLocalizationOptions>(opts =>
            {
                opts.SupportedCultures = new[] { new CultureInfo("en"), new CultureInfo("fr") };
                opts.SupportedUICultures = opts.SupportedCultures;
                opts.SetDefaultCulture("en");
                opts.DefaultRequestCulture = new RequestCulture("en");
                opts.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider);
                opts.ApplyCurrentCultureToResponseHeaders = opts.ApplyCurrentCultureToResponseHeaders;
            });

            services.AddControllersWithViews(opts =>
            {
                opts.Filters.Add(new CultureFilter("en"));
            });

            services.AddLocalization();
            services.AddMvc();
        }

我有一个ActionFilter,它根据路由值设置用户的文化。

public class CultureFilter : IAuthorizationFilter
    {
        private readonly string defaultCulture;

        public CultureFilter(string defaultCulture)
        {
            this.defaultCulture = defaultCulture;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var values = context.RouteData.Values;

            string culture = (string)values["culture"] ?? this.defaultCulture;

            CultureInfo ci = new CultureInfo(culture);

            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(ci.Name);
        }
    }

使用默认的路由约定,我得到了想要的结果(或多或少)。
因此,对于以下途径:

endpoints.MapControllerRoute(
    name: "culture-default",
    pattern: "{culture=en}/{controller=Home}/{action=Index}");

endpoints.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}");

因此,在URL "http://localhost"上,我得到:"@URL.操作链接("索引","主页")"=" http://localhost ""@URL.操作链接("隐私","主页")"="http://localhost/主页/隐私"
而在网址"http://localhost/fr"上,我得到:"@URL.操作链接("索引","主页")"=" http://localhost/fr ""@URL.操作链接("隐私","主页")"="http://localhost/fr/home/privacy"
好吧-到目前为止一切顺利....
但是,当我为Privacy ActionMethod添加自定义路由时,似乎无法在生成的URL中获得正确的文化。
因此,对于以下途径:

endpoints.MapControllerRoute(
    name: "culture-privacy",
    pattern: "{culture}/h/p",
    defaults: new { culture = "en", controller = "Home", action = "Privacy" });

endpoints.MapControllerRoute(
    name: "default-privacy",
    pattern: "h/p",
    defaults: new { controller = "Home", action = "Privacy" });

因此,在URL "//localhost "上,我得到:"@网址操作链接("索引","主页")"= "//本地主机" "@网址操作链接("隐私","主页")"= "//本地主机/h/p"
而在URL "//localhost/fr "上,我得到:"@URL.操作链接("索引","主页")"= "//本地主机/fr" "@URL.操作链接("隐私","主页")"= "//本地主机/en/h/p"
这可能是因为我在"culture-privacy"路由的默认值中包含了"culture ='en'",但是,如果路由中没有指定文化,那么不应该使用默认值'en'吗?

falq053o

falq053o1#

您是对的,原因是默认值“en”覆盖了路由数据中传递的值。如果要使用用户键入的区域性,请尝试使用路由数据中传递的区域性值,而不是固定值。以下是代码示例:

endpoints.MapControllerRoute(
name: "culture-privacy",
pattern: "{culture}/h/p",
defaults: new { culture = "{culture}", controller = "Home", action = "Privacy" });

相关问题