Search code examples
asp.net-mvcasp.net-mvc-4localizationglobalization

Url Localization in MVC web Project


I have a multi-language page where I store the culture info in a cookie. But now I will change it to URL localization. Url should look like

www.domain.com/en/home/index or www.domain.com/fr/home/index

I tried a lot of solution but nothing worked good. Now I have a solution but it only works in route but not with areas.

in Global.asax I register the routes like

   protected void Application_Start()
    {
     //   ViewEngines.Engines.Clear();

        //LocalizedViewEngine: this is to support views also when named e.g. Index.de.cshtml
        ViewEngines.Engines.Insert(0, new LocalizedViewEngine());

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);



        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        //standard mvc4 routing. see App_Start\RouteConfig.cs
        //RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
    }



        public static void RegisterRoutes(RouteCollection routes)
    {
        const string defautlRouteUrl = "{controller}/{action}/{id}";

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        RouteValueDictionary defaultRouteValueDictionary = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional });
        routes.Add("DefaultGlobalised", new GlobalisedRoute(defautlRouteUrl, defaultRouteValueDictionary));
        routes.Add("Default", new Route(defautlRouteUrl, defaultRouteValueDictionary, new MvcRouteHandler()));

        //LocalizedViewEngine: this is to support views also when named e.g. Index.de.cshtml
        routes.MapRoute(
            "Default2",
            "{culture}/{controller}/{action}/{id}",
            new
            {
                culture = string.Empty,
                controller = "Home",//ControllerName
                action = "Index",//ActionName
                id = UrlParameter.Optional
            }
        ).RouteHandler = new LocalizedMvcRouteHandler();
    }

and in every AreaRegistration I have this overwrite

 public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Doc_default",
            "Doc/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );

        //LocalizedViewEngine: this is to support views also when named e.g. Index.de.cshtml
        context.MapRoute(
            "Doc_default2",
            "{culture}/Doc/{controller}/{action}/{id}",
            new
            {
                culture = string.Empty,
                controller = "Doc",
                action = "Index",
                id = UrlParameter.Optional
            }
        ).RouteHandler = new LocalizedMvcRouteHandler();
    }

I spent hours for this problem, but I don't get it! Is there a good tutorial for MVC URL localization?

Thanks for Help!


Solution

  • So now I have the solution for me. And it workes great.

    I have now in registerRroutes and RegisterArea

    public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                    name: "Default_Localization",
                    url: "{language}/{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, language = string.Empty }
                    );
        }
    

    And then the BaseController

      protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
        {
    
            string cultureName;
            if (RouteData.Values.ContainsKey("language") && !string.IsNullOrWhiteSpace(RouteData.Values["language"].ToString()))
            {
                cultureName = RouteData.Values["language"].ToString();
            }
            else
            {
                cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? CultureHelper.GetNeutralCulture(Request.UserLanguages[0]) : null;
                cultureName = CultureHelper.GetImplementedCulture(cultureName);
            }
    
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName.ToLower());
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName.ToLower());
    
            return base.BeginExecuteCore(callback, state);
        }
    
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
    
            var cultureName = CultureHelper.GetNeutralCulture(CultureHelper.GetCurrentCulture());
            cultureName = CultureHelper.GetImplementedCulture(cultureName);
            filterContext.RouteData.Values["language"] = cultureName.ToUpper();
        }
    

    Thats it!