首页 > 解决方案 > Razor Pages: Set cookie from _Layout.cshtml

问题描述

In _Layout.cshtml I have menu to change language of the application, like:

<nav id="nav-lang">
                    <ul>
                        <li>
<a href="?culture=en-EN">EN</a>
                        </li>
                        <li>
                            <a href="?culture=pl-PL">PL</a>
                        </li>
                    </ul>
                
            </nav>

What it does is reloading the page and sets new culture - works well. The thing is, that if the user changes culture and then go to other page within my app, default culture is loaded. I checked my options and the best choice seems to be setting a cookie "UserCulture" to e.g. "c=pl-PL|uic=pl-PL". The thing is I don't really know how to do it from in razor pages. I think that I should have a with asp-page-handler set to some method (e.g. "SetCulture") and have setting cookie in that method, but this causes some problems:

I might be missing something very basic here, I'm quite new to Razor Pages still. From the hindsight I should have probably sticked to MVC but Razor Pages was said to be easier..

标签: c#asp.net-coreculturerazor-pages

解决方案


Thanks, Brad. The solution you proposed works well. In the meantime I've got also other suggestion elsewhere and I'll post it too for anyone searching the answer in future.

In _Layout.cshtml:

<nav id="nav-lang">
    <ul>
        <li><a asp-page="/Index" asp-page-handler="SetCulture" asp-route-culture="en-EN">EN</a></li>
        <li><a asp-page="/Index" asp-page-handler="SetCulture" asp-route-culture="pl-PL">PL</a></li>
    </ul>
</nav>

In code-behind of Index (or any other page having code-behind):

public async Task<IActionResult> OnGetSetCultureAsync(string culture)
        {
            HttpContext.Response.Cookies.Append("Culture", "c=" + culture + "|uic=" + culture);
            var returnUrl = Request.Headers["Referer"].ToString();
            if (returnUrl.Contains("?culture="))
            {
                var url = returnUrl.Substring(0, returnUrl.IndexOf("?culture=")); 
                return Redirect(url + "?culture=" + culture);
            }
            else
            {
                return Redirect(returnUrl + "?culture=" + culture);
            }

        }

And of course, for both solutions to work, there must be info in Startup.cs >> Configure:

var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("pl-PL")
            };

            var lo = new RequestLocalizationOptions // Localization Options
            {
                DefaultRequestCulture = new RequestCulture("en-US"),
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            };

            var cp = lo.RequestCultureProviders.OfType<CookieRequestCultureProvider>().First(); // Culture provider
            cp.CookieName = "Culture";

推荐阅读