mr.
mr.

Reputation: 679

How to change asp.net mvc5 web app current localization culture with refreshing the same page?

I want to change localization culture of the project with refreshing the current page only. To do this, i want to put two href to the layout.I tried a lot to getting current request both view and controller but i did not achieve this. My route config as below;

routes.MapRoute(
            name: "Default",
            url: "{lang}/{controller}/{action}/{id}",
            constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },
            defaults: new { controller = "Home", action = "Index",Lang="tr", id = UrlParameter.Optional }
        );

Also my attribute as below;

public class LocalizationAttribute: ActionFilterAttribute
{

    private string _DefaultLanguage = "tr";

    public LocalizationAttribute(string defaultLanguage)
    {
        _DefaultLanguage = defaultLanguage;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string lang = (string)filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
        if (lang != _DefaultLanguage)
        {
            try
            {
                Thread.CurrentThread.CurrentCulture =
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
            }
            catch (Exception e)
            {
                throw new NotSupportedException(String.Format("ERROR: Invalid language code '{0}'.", lang));
            }
        }
    }

}

when i try to use

 <a href='@Url.Action("ChangeLanguage","Home",new { @lang="tr",@returnurl=this.Request.RawUrl})'>Türkçe</a>

or sth like that, parameters disappearing or the url not showing sometimes like Index actions ? Is there any way to refresh exactly same page with only changing the "lang" of the route?

Upvotes: 1

Views: 1287

Answers (1)

teran
teran

Reputation: 3234

while your routes contain only one default route lang, controller, action, id params in URL you can use code like snippet below to add links for different cultures in _layout.

    @{
        var locales = new Dictionary<string, string>() { { "en", "eng" }, { "ru", "rus" } };            

        var controller = Url.RequestContext.RouteData.Values["controller"].ToString();
        var action = Url.RequestContext.RouteData.Values["action"].ToString();
        var id = Url.RequestContext.RouteData.Values["id"];

    }
    <ul id="changeLang">            
        @foreach (var l in locales) {
            <li>@Html.ActionLink(l.Value, action, controller, new { lang = l.Key, id = id}, null)</li>
        }
    </ul>
    @RenderBody()

but this approach work fine only for Default-route pattern. When you add other params to request it will not work.

update as an option, you can generate links on the client side, using jquery and the knowledge of current lang, but you should white correct rexep to replace lang.

<script type="text/javascript">
    $(function () {
        var locales = [{ key: 'ru', title: 'rus' }, { key: 'en', title: 'eng' }];

        var cl = '@Url.RequestContext.RouteData.Values["lang"]';
        var curl = '@Request.RawUrl';
        var rexp = new RegExp("\/{LANG}\/?".replace("/{LANG}/", cl), "i");

        $.each(locales, function (idx, l) {
            var link = $("<a>").attr("href", curl.replace(rexp, l.key)).text(l.title);
            $("ul#jlang").append($("<li>").append(link));
        });
    });
</script>

update 2 mixed server side and client side code:

  1. render locales menu at server side

    @{
        var locales = new Dictionary<string, string>() { { "en", "eng" }, { "ru", "rus" } };
    }
    <ul id="changeLang">            
        @foreach (var l in locales) {
            <li><a href="#" id="@l.Key">@l.Value</a></li>
        }
    </ul>
    
  2. change url at client side

        $("#changeLang a").click(function (e) {
            e.preventDefault();
            var tl = $(this).attr("id");
            var cl = '@Url.RequestContext.RouteData.Values["lang"]';
            var rexp = new RegExp("\/{LANG}\/?".replace("/{LANG}/", cl), "i");            
    
            window.location = window.location.href.replace(rexp, tl);
        });        
    

Upvotes: 2

Related Questions