Quantcast
Channel: MIKE » SQL Server
Viewing all articles
Browse latest Browse all 3

ASP.NET MVC and Localization

$
0
0

I live in Montreal – Canada, and here we have two officials languages, French and English, that’s why every website I build must be available in both languages. Building an ASP.NET MVC Website using Localization/Globalization is fairly simple and is pretty much like doing it on a plain old ASP.NET Website.

We will start this example from a blanc ASP.NET MVC Website. This will be easier for you to follow. Now that you have your new ASP.NET MVC Website, create a new class and name it SetCultureAttribute.cs in a new ActionFilter directory and paste this code inside of it.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.ActionFilter
{
    public class SetCultureAttribute : FilterAttribute, IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext 
            filterContext)
        {
            string cultureCode = SetCurrentLanguage(filterContext);

            
            if (string.IsNullOrEmpty(cultureCode)) return;

            HttpContext.Current.Response.Cookies.Add(
                new HttpCookie("Culture", cultureCode)
                {
                    HttpOnly = true, 
                    Expires = DateTime.Now.AddYears(100)
                }
            );
            
            filterContext.HttpContext.Session["Culture"] = cultureCode;

            CultureInfo culture = new CultureInfo(cultureCode);
            System.Threading.Thread.CurrentThread.CurrentCulture = 
                culture;
            System.Threading.Thread.CurrentThread.CurrentUICulture = 
                culture;
        }

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            
        }

        private static string GetCookieCulture(ActionExecutingContext 
            filterContext, ICollection Cultures)
        {
            /* Get the language in the cookie*/
            HttpCookie userCookie = filterContext.RequestContext
                                                .HttpContext
                                                .Request
                                                .Cookies["Culture"];

            if (userCookie != null)
            {
                if (!string.IsNullOrEmpty(userCookie.Value))
                {
                    if (Cultures.Contains(userCookie.Value))
                    {
                        return userCookie.Value;
                    }
                    return string.Empty;
                }
                return string.Empty;
            }
            return string.Empty;
        }

        private static string GetSessionCulture(ActionExecutingContext 
            filterContext, ICollection Cultures)
        {
            if (filterContext.RequestContext.HttpContext
                                               .Session["Culture"] 
                                                             != null)
            {
                string SessionCulture = filterContext.RequestContext
                                                .HttpContext
                                                .Session["Culture"]
                                                .ToString();

                if (!string.IsNullOrEmpty(SessionCulture))
                {
                    return Cultures.Contains(SessionCulture) 
                                 ? SessionCulture 
                                 : string.Empty;
                }
                return string.Empty;
            }
            return string.Empty;
        }

        private static string GetBrowserCulture(ActionExecutingContext 
            filterContext, IEnumerable Cultures)
        {
            /* Gets Languages from Browser */
            IList BrowserLanguages = filterContext.RequestContext
                                                         .HttpContext
                                                         .Request
                                                         .UserLanguages;

            foreach (var thisBrowserLanguage in BrowserLanguages)
            {
                foreach (var thisCultureLanguage in Cultures)
                {
                    if (thisCultureLanguage != thisBrowserLanguage) 
                        continue;

                    return thisCultureLanguage;
                }
            }
            return string.Empty;
        }

        private static string SetCurrentLanguage(ActionExecutingContext 
             filterContext)
        {
            IList Cultures = new List 
            {
                "en-CA", 
                "fr-CA"
            };

            string CookieValue = GetCookieCulture(
                                            filterContext, 
                                            Cultures);

            if (string.IsNullOrEmpty(CookieValue))
            {
                string SessionValue = GetSessionCulture(
                                                  filterContext, 
                                                  Cultures);

                if (string.IsNullOrEmpty(SessionValue))
                {
                    string BrowserCulture = GetBrowserCulture(
                                                         filterContext, 
                                                         Cultures);
                    return string.IsNullOrEmpty(BrowserCulture) 
                             ? "en-CA" 
                             : BrowserCulture;
                }
                return SessionValue;
            }
            return CookieValue;
        }
    }
}

Once this is done, we need to tell our controllers to use this attribute, to do this we could simply go on top of every controller and decorate it with [SetCulture] attribute. The down side with this is that we want the complete site multicultural, not just a few controllers or actions. To fix this problem we’ll make a BaseController which will inherit Controller and will be inherited from all our controllers.

To do this, create a new directory and name it Infrastructure and then add a new class called BaseController.cs in it. This class should contain the following code:

using System.Web.Mvc;
using MvcApplication1.ActionFilter;

namespace MvcApplication1.Infrastructure
{
    [SetCulture]
    public class BaseController : Controller 
    {
         // Anything you put here will be accessible 
         // in every controllers
    }
}

As I said before, we need to tell every controllers to use BaseController, so open every controllers and change the inheritance from Controller to BaseController. As of now, your website knows how to handle localization!!!

What we need now, is a way to switch between french and english… To do this I simply created a new ASP.NET MVC View User Controller (CultureUserControl.ascx) in Views/Shared with the following code.

<% if (Session["Culture"].ToString() == "en-CA") {%>
    [ Français ]
<% } else if (Session["Culture"].ToString() == "fr-CA") { %>
    [ English ] 
<% } %>

Then I added it to the masterpage, right next to the Log On link.

<% Html.RenderPartial("LogOnUserControl"); %> <% Html.RenderPartial("CultureUserControl"); %>

Last, but not least, add a new Global.resx and Global.fr.rex in the App_GlobalResources folder. You can start with the welcome message in About – Index and call it using Resources.Global.Welcome

1121

You can find a working example of this tutorial here.


Viewing all articles
Browse latest Browse all 3