Click here to Skip to main content
15,897,273 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,

I try to do my first own website in mvc3.
I read a lot of article about multilanguage website and tried different approach without real success.
My last tactic is : to pass the culture info in url and use routemanager to set the good culture:

C#
public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
             "Default", // Route name
             "{controller}/{action}/{id}", // URL with parameters
             new { controller = "Home", action = "Home",
              id = UrlParameter.Optional } // Parameter defaults
        );

        foreach (Route r in routes)
        {
            if (!(r.RouteHandler is SingleCultureMvcRouteHandler))
            {
                r.RouteHandler = new MultiCultureMvcRouteHandler();
                r.Url = "{culture}/" + r.Url;
                //Adding default culture
                if (r.Defaults == null)
                {
                    r.Defaults = new RouteValueDictionary();
                }
                r.Defaults.Add("culture", CultureEnum.en);

                //Adding constraint for culture param
                if (r.Constraints == null)
                {
                    r.Constraints = new RouteValueDictionary();
                }
                r.Constraints.Add("culture",
                new CultureConstraint(CultureEnum.en, CultureEnum.fr));
            }
        }
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
        //CultureHelper.SetCulture(Thread.CurrentThread.CurrentCulture);
    }
}

#region Localisation Class
public class SingleCultureMvcRouteHandler : MvcRouteHandler { }

public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(
         RequestContext requestContext)
    {
        var culture = requestContext.RouteData.Values["culture"].ToString();
        var ci = new CultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = ci;
        Thread.CurrentThread.CurrentCulture =
            CultureInfo.CreateSpecificCulture(ci.Name);
        //CultureHelper.SetCulture(Thread.CurrentThread.CurrentCulture);

        return base.GetHttpHandler(requestContext);
    }
}

public class CultureConstraint : IRouteConstraint
{
    private string[] _values;
    public CultureConstraint(params string[] values)
    {
        this._values = values;
    }

    public bool Match(HttpContextBase httpContext,
    Route route, string parameterName,
    RouteValueDictionary values, RouteDirection routeDirection)
    {

        // Get the value called "parameterName" from the
        // RouteValueDictionary called "value"
        string value = values[parameterName].ToString();
        // Return true is the list of allowed values contains
        // this value.
        return _values.Contains(value);
    }
}

public class CultureEnum
{
    public static string fr = "fr-FR";
    public static string en = "en-US";
}
#endregion


The routemanager work well. All time I switch the language, I saw the url change. The Thread.CurrentThread.CurrentUICulture and Thread.CurrentThread.CurrentCulture are set propertly. But:
- All time in page, it's the default language (neutral resx) who is displayed.
- If change my language again, I saw CurrentUICulture and CurrentCulture have my user language (fr) yet but still display the neutral default.

I try to put my 3 resx files (toto.resx, toto.fr-FR.resx, toto.en-US.resx)in multiple locations (global, local, myproject.Resources, etc...) nothing change.
It's all time the Default resx displayed.

I try to change the resourcesgenerator as ResXFileCodeGenerator, PublicResXFileCodeGenerator, etc... but same results.

The only trick, I found after one long and hard day is:
C#
public static void SetCulture(CultureInfo newCulture)
{
            if (newCulture == null)
                return;

            var classLi = from t in Assembly.GetExecutingAssembly().GetTypes()
                          where t.IsClass && t.Namespace == ResourcesNamespace
                          select t;

            foreach (Type t in classLi)
            {
                PropertyInfo pi = t.GetProperty("Culture");
                if (pi != null)
                {
                    pi.SetValue(t, newCulture, null);
                }
            }
        }
    }


It's ugly but it works. But I a afraid this solution will fail with multiple users.


So ladies and gentlemen if you have the kindness to share your ideas :)
Posted

1 solution

Hi,

The following tutorial takes you step by step through exactly what you're trying to do; Using resource files and culture information to provide translations.

Developing Multi Language Web Sites with ASP.NET[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900