Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC5 Change language/culture by clicking on Html.ActionLink

I have a problem problem with my ASP.NET MVC5 appliaction. My app can set lang/culture which is set in the browser (only English and Polish (default) now). I want to let users change language/culture by clicking on Html.ActionLink.

I created a class:

namespace Guestbook
{
    public static class Click
    {
        public static void SetCulture(string name)
        {
            Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(name);
            Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
        }

    }
}

And I have in my View:

@Html.ActionLink("PL", "", "Guests", routeValues: null, htmlAttributes: new { onclick = "SetCulture(\"pl\");" })
@Html.ActionLink("EN", "", "Guests", routeValues: null, htmlAttributes: new { onclick = "SetCulture(\"en\");" })

Of course, it doesn't work. What do I need more? JavaScript function?

like image 635
Zashi Avatar asked Jan 10 '23 13:01

Zashi


2 Answers

The simplest answer would be that you need to create an controller which you then link to.

public class LanguageController : Controller
{
    public ActionResult SetLanguage(string name)
    {
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(name);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        HttpContext.Current.Session["culture"] = name;

        return RedirectToAction("Index", "Home");
    }
}

Then in your view:

<a href="@Url.Action("SetLanguage", "Language", new { @name = "pl" })">Polski</a>
<a href="@Url.Action("SetLanguage", "Language", new { @name = "en" })">English</a>

You might consider storing user-data in session or similar.

EDIT:

For instance you could use the Application_BeginRequest event in the global.asax.

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    var name = HttpContext.Current.Session["culture"] as string;

    if (string.IsNullOrEmpty(name))
    {
        return;
    }

    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(name);
    System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;
}

EDIT:

Save the cookie in the SetLanguage action:

var cookie = new HttpCookie("_culture", name);
cookie.Expires = DateTime.Today.AddYears(1);
Response.SetCookie(cookie);

Fetch the cookie in Application_BeginRequest:

var cookie = HttpContext.Current.Request.Cookies["_culture"];
var name = cookie != null ? cookie.Value : null;
like image 181
Olivier Avatar answered Feb 03 '23 06:02

Olivier


I created a small controller and edit my View. @Olivier (thanks mate!) showed me a way how to do it, but it didn't work, because my app stores culture in a cookie, not in a session.

Controller:

public class LanguageController : BaseController
    {
        // GET: Language
        public ActionResult SetLanguage(string name)
        {
            Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(name);
            Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

            HttpCookie cultureCookie = new HttpCookie("_culture");
            cultureCookie.Value = name;
            cultureCookie.Expires = DateTime.UtcNow.AddYears(1);

            Response.Cookies.Remove("_culture");
            Response.SetCookie(cultureCookie);


            return RedirectToAction("Index", "Guests");
        }
    }

LanguageController inherits from BaseController (which inherits from Controller), because I used this tutorial: ASP.NET MVC 5 Internationalization by Nadeem Afana

In my View:

<a href="@Url.Action("SetLanguage", "Language", new { @name = "pl" })">Polski</a>
<a href="@Url.Action("SetLanguage", "Language", new { @name = "en" })">English</a>
like image 43
Zashi Avatar answered Feb 03 '23 07:02

Zashi