Building a Multilingual Web Application Using .NET - Part Two

Introduction

 
In this article, we will learn a step by step process to create a multilingual Web application using ASP.NET MVC. Multilingual means we can implement the website in multiple languages.
 
In today's world to grow customer interaction, everyone needs to implement this procedure in their applications.
 
Prerequisites
  • Visual Studio
Note
Before going through this session, visit my previous articles related to ASP.NET MVC for better understanding.
 
Step 1
 
First, we need to add Resource File for different languages:
  1. Resource.resx - This is the default resource file for the English language.
  2. Resource.es.resx - This resource file is associated with the Spanish language.
  3. Resource.bn.resx - This resource file is associated with the Bengali language.
  4. Resource.or.resx - This resource file is associated with the Oriya language.
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Add New > Select Resource File under General > Enter File name > Add.
 
Set all the resource files Access Modifier to Public as mentioned in below image:
 
Building 🏗️ Multilingual Web Application Using .NET
 
Step 2
 
In this step, we need to add a class file in the Model folder to configure field validation setup.
 
Go to Solution Explorer > Right Click on Modules folder > Add > Class > Enter Class name (SignUp.cs) > Add.
 
Code Ref
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. using System.ComponentModel.DataAnnotations;  
  7. using System.ComponentModel;  
  8.   
  9. namespace MultilingualMVCApp.Models  
  10. {  
  11.     public class SignUp  
  12.     {  
  13.           
  14.         [Display(Name = "FirstName", ResourceType = typeof(Resource))]  
  15.         [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "FirstNameRequired")]  
  16.         public string FirstName { getset; }  
  17.   
  18.         [Display(Name = "LastName", ResourceType = typeof(Resource))]  
  19.         [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "LastNameRequired")]  
  20.         public string LastName { getset; }  
  21.   
  22.         [Display(Name = "Email", ResourceType = typeof(Resource))]  
  23.         [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "EmailRequired")]  
  24.         [RegularExpression(@"^([0-9a-zA-Z]([\+\-_\.][0-9a-zA-Z]+)*)+@(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]*\.)+[a-zA-Z0-9]{2,3})$",  
  25.             ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "EmailInvalid")]  
  26.         public string Email { getset; }  
  27.   
  28.         [Display(Name = "Age", ResourceType = typeof(Resource))]  
  29.         [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "AgeRequired")]  
  30.         [Range(18, 60, ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "AgeRange")]  
  31.         public int Age { getset; }  
  32.   
  33.         [Display(Name = "Phone", ResourceType = typeof(Resource))]  
  34.         [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "PhnRequired")]  
  35.         [RegularExpression(@"^([0-9]{10})$", ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "PhnRange")]  
  36.         public string Phone { getset; }  
  37.     }  
  38. }  
Code Description
 
Here, the typeof(Resource) is the file name for resources. All input fields have field validation for empty and if any input is not valid. Below, these namespaces are important for showing field names and validation messages to the user.
  1. using System.ComponentModel.DataAnnotations;    
  2. using System.ComponentModel;  
Step 3
 
In this step, we need to add another class to manage and setup language property & function that is based on language selection the all field text and validation text of input fields are translated accordingly.
 
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Class > Enter Class Name (LangTrans.cs) > Add. 
 
Code Ref
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Globalization;  
  4. using System.Linq;  
  5. using System.Threading;  
  6. using System.Web;  
  7.   
  8. namespace MultilingualMVCApp  
  9. {  
  10.     public class LangTrans  
  11.     {  
  12.         public static List<Languages> AvailableLanguages = new List<Languages> //add language name and its culture name based on resource files.  
  13.         {  
  14.              new Languages{ LangFullName = "English", LangCultureName = "en"},  
  15.              new Languages{ LangFullName = "Español", LangCultureName = "es"},  
  16.              new Languages{ LangFullName = "বাংলা", LangCultureName = "bn"},  
  17.              new Languages{ LangFullName = "ଓଡିଆ", LangCultureName = "or"}  
  18.         };  
  19.   
  20.         public static bool IsLanguageAvailable(string lang) //Here all added languages are available  
  21.         {  
  22.             return AvailableLanguages.Where(a => a.LangCultureName.Equals(lang)).FirstOrDefault() != null ? true : false;  
  23.         }  
  24.   
  25.         public static string GetDefaultLanguage() //On page load the default language selection is English.  
  26.         {  
  27.             return AvailableLanguages[0].LangCultureName;  
  28.         }  
  29.   
  30.         public void SetLanguage(string lang) //Here language selection with property and function setup  
  31.         {  
  32.             try  
  33.             {  
  34.                 if (!IsLanguageAvailable(lang))  
  35.                     lang = GetDefaultLanguage();  
  36.                 var cultureInfo = new CultureInfo(lang);  
  37.                 Thread.CurrentThread.CurrentUICulture = cultureInfo;  
  38.                 Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);  
  39.                 HttpCookie langCookie = new HttpCookie("culture", lang);  
  40.                 langCookie.Expires = DateTime.Now.AddYears(1);  
  41.                 HttpContext.Current.Response.Cookies.Add(langCookie);  
  42.   
  43.             }  
  44.             catch (Exception ex)  
  45.             {  
  46.   
  47.             }  
  48.         }  
  49.     }  
  50.   
  51.     public class Languages //Declare object names  
  52.     {  
  53.         public string LangFullName { getset; }  
  54.         public string LangCultureName { getset; }  
  55.     }  
  56. }  
Code Description
 
Here I added code with a description in a green comment mark "//" at one place for better and faster understanding.
 
Step 4
 
In this step, we add another class that acts as an inherit Controller, where BeginExecuteCore can be overridden. It is added for checking & set language each time any request execute.
 
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Class > Enter Class Name (MyCommonController.cs) > Add.
 
Code Ref
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6.   
  7. namespace MultilingualMVCApp  
  8. {  
  9.     public class MyCommonController:Controller  
  10.     {   
  11.         protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)  
  12.         {  
  13.             string lang = null;  
  14.             HttpCookie langCookie = Request.Cookies["culture"];  
  15.             if (langCookie != null)  
  16.             {  
  17.                 lang = langCookie.Value;
  18.             }  
  19.             else  
  20.             {  
  21.                 var userLanguage = Request.UserLanguages;  
  22.                 var userLang = userLanguage != null ? userLanguage[0] : "";  
  23.                 if (userLang != "")  
  24.                 {  
  25.                     lang = userLang;  
  26.                 }  
  27.                 else  
  28.                 {  
  29.                     lang = LangTrans.GetDefaultLanguage(); // Using LangTrans class we get default language  
  30.                 }  
  31.             }  
  32.   
  33.             new LangTrans().SetLanguage(lang); // Using LangTrans class, We set language selection with property and function   
  34.   
  35.             return base.BeginExecuteCore(callback, state);  
  36.         }  
  37.     }  
  38. }  
Code Description
 
Here I added code with a description in green comment mark "//" at one place for better and faster understanding.
 
Step 5
 
In this step, we need to add new action into your controller for the Get Action method. Here, I have added the "Lang" Action into "Home" Controller. Please write this following code:
 
Code Ref 
  1. public ActionResult Lang()  
  2.         {  
  3.             return View();  
  4.         }  
Step 6
 
In this step, we need to add a view for the Action & design. Right-click on Action Method (here right-click on form action) > Add View... > Enter View Name >
 
Building 🏗️ Multilingual Web Application Using .NET
 
Code Ref
  1. @*inherit model calss file to access all input fields and its validation message.*@  
  2. @model MultilingualMVCApp.Models.SignUp  
  3.   
  4. @{  
  5.     //Here title translated according to language selection based on resourse file.  
  6.     ViewBag.Title = MultilingualMVCApp.Resource.Register;  
  7. }  
  8.   
  9. <h2>@MultilingualMVCApp.Resource.Register</h2>  
  10.   
  11.   
  12. @using (Html.BeginForm())  
  13. {  
  14.     @Html.AntiForgeryToken()  
  15.   
  16.     <div class="form-horizontal">  
  17.         @*All input fields validation messages are mentioned.*@  
  18.         <hr />  
  19.         @Html.ValidationSummary(true""new { @class = "text-danger" })  
  20.         <div class="form-group">  
  21.             @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })  
  22.             <div class="col-md-10">  
  23.                 @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })  
  24.                 @Html.ValidationMessageFor(model => model.FirstName, ""new { @class = "text-danger" })  
  25.             </div>  
  26.         </div>  
  27.   
  28.         <div class="form-group">  
  29.             @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })  
  30.             <div class="col-md-10">  
  31.                 @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })  
  32.                 @Html.ValidationMessageFor(model => model.LastName, ""new { @class = "text-danger" })  
  33.             </div>  
  34.         </div>  
  35.   
  36.         <div class="form-group">  
  37.             @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })  
  38.             <div class="col-md-10">  
  39.                 @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })  
  40.                 @Html.ValidationMessageFor(model => model.Email, ""new { @class = "text-danger" })  
  41.             </div>  
  42.         </div>  
  43.   
  44.         <div class="form-group">  
  45.             @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" })  
  46.             <div class="col-md-10">  
  47.                 @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } })  
  48.                 @Html.ValidationMessageFor(model => model.Age, ""new { @class = "text-danger" })  
  49.             </div>  
  50.         </div>  
  51.   
  52.         <div class="form-group">  
  53.             @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })  
  54.             <div class="col-md-10">  
  55.                 @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })  
  56.                 @Html.ValidationMessageFor(model => model.Phone, ""new { @class = "text-danger" })  
  57.             </div>  
  58.         </div>  
  59.   
  60.         <div class="form-group">  
  61.             <div class="col-md-offset-2 col-md-10">  
  62.                 <input type="submit" value="@MultilingualMVCApp.Resource.Submit" class="btn btn-default" />  
  63.                 <input type="reset" value="@MultilingualMVCApp.Resource.Reset" class="btn btn-reset" />  
  64.             </div>  
  65.         </div>  
  66.     </div>  
  67. }  
  68.   
  69. @*<div>  
  70.         @Html.ActionLink("Back to List""Index")  
  71.     </div>*@  
  72.   
  73. @section Scripts {  
  74.     @Scripts.Render("~/bundles/jqueryval")  
  75. }  
Code Description
 
Here I added code with a description in a green comment mark "//" and "@* *@" at one place for better and faster understanding.
 
Step 7
 
Here, we need to add another action to your controller for the POST Method. Here, I have added "Lang" Action into "HomeController" Controller for POST Action. Please write the following code:
 
Code Ref
  1. [HttpPost]  
  2.         public ActionResult Lang(SignUp r)  
  3.         {  
  4.             return View(r);  
  5.         }  
Step 8
 
In this step, we need to add another action to your controller for Change Language. Here, I have added "ChangeLanguage" Action into "HomeController" Controller for changing the language. Please write the following code:
 
Code Ref
  1. public ActionResult ChangeLanguage(string lang)  
  2.         {  
  3.             new LangTrans().SetLanguage(lang);  
  4.             return RedirectToAction("Lang""Home");  
  5.         }  
Step 9
 
Here, we need to modify the layout page for showing available languages.
 
Code Ref
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  6.     <title>@ViewBag.Title - My ASP.NET Application</title>  
  7.     @Styles.Render("~/Content/css")  
  8.     @Scripts.Render("~/bundles/modernizr")  
  9. </head>  
  10. <body>  
  11.     <div class="navbar navbar-inverse navbar-fixed-top">  
  12.         <div class="container">  
  13.             <div class="navbar-header">  
  14.                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">  
  15.                     <span class="icon-bar"></span>  
  16.                     <span class="icon-bar"></span>  
  17.                     <span class="icon-bar"></span>  
  18.                 </button>  
  19.             </div>  
  20.             <div class="navbar-collapse collapse">  @*This one added for collapse of all languages based on screen resolution.*@  
  21.                 <ul class="nav navbar-nav">  
  22.                         @* Here i added for selection of available Languages *@  
  23.                         @{  
  24.                             foreach (var i in MultilingualMVCApp.LangTrans.AvailableLanguages)  
  25.                             {  
  26.                     <li style="color:white; font-size:large">@Html.ActionLink(i.LangFullName, "ChangeLanguage""Home"new { lang = i.LangCultureName }, null) <text> </text></li>  
  27.                             }  
  28.                         }     
  29.                     </ul>  
  30.             </div>  
  31.              
  32.         </div>  
  33.     </div>  
  34.     <div class="container body-content">  
  35.         @RenderBody()  
  36.         <hr />  
  37.     </div>  
  38.   
  39.     @Scripts.Render("~/bundles/jquery")  
  40.     @Scripts.Render("~/bundles/bootstrap")  
  41.     @RenderSection("scripts", required: false)  
  42. </body>  
  43. </html>  
Code Description
 
Here, I added code with a description in a green comment mark "//" and "@* *@" at one place for better and faster understanding.
 
Step 10
 
Here, we set as start page in MVC in the RouteConfig.cs file.
 
Code Ref
  1. routes.MapRoute(  
  2.                 name: "Default",  
  3.                 url: "{controller}/{action}/{id}",  
  4.                 defaults: new { controller = "Home", action = "Lang", id = UrlParameter.Optional }  
  5.             );  
Output
 
The content is translated into English.
 
Building 🏗️ Multilingual Web Application Using .NET
 
The content is translated into Spanish.
 
Building 🏗️ Multilingual Web Application Using .NET
 
The content is translated into the Bengali language.
 
Building 🏗️ Multilingual Web Application Using .NET
 
The content is translated into the Oriya language.
 
Building 🏗️ Multilingual Web Application Using .NET
 
The validation message content is translated into the English language.
 
Building 🏗️ Multilingual Web Application Using .NET
 
The validation message content is translated into the Oriya language.
 
Building 🏗️ Multilingual Web Application Using .NET
 
Link To Source Code:

Summary

 
In this article, we have learned:
  • Introduction to multilingual Asp.net MVC Application
  • Configure resource files in MVC Application
  • Way to set-up ISO Language code for translating content
  • Manage Languages property and function using C#