Sunday, August 11, 2019

How to create multilingual website in asp.net mvc4

Step - 1: Create New Project.

Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Basic > Select view engine Razor > OK

Step - 2: Add Resource File for different languages

Here I have added 3 resource file for 3 languages
  1. Resource.resx - This is the default resource file associated with 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.
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Add New > Select Resource File under General > Enter File name > Add.

[N.B: Don't forget to change all the resource files Access Modifier to Public ] 





Step - 3 : Create a Class (Module)

Go to Solution Explorer > Right Click on Modules folder > Add > Class > Enter Class name > Add.


  1. using System.ComponentModel.DataAnnotations;
  2. namespace MvcMultilingual.Models
  3. {
  4. public class RegistrationModel
  5. {
  6. // Here typeof(Resource) is The File Name Start With for resources
  7. [Display(Name="FirstName", ResourceType=typeof(Resource))]
  8. [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "FirstNameRequired")]
  9. public string FirstName { get; set; }
  10.  
  11. [Display(Name = "LastName", ResourceType = typeof(Resource))]
  12. [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "LastNameRequired")]
  13. public string LastName { get; set; }
  14.  
  15. [Display(Name = "Email", ResourceType = typeof(Resource))]
  16. [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "EmailRequired")]
  17. [RegularExpression(@"^([0-9a-zA-Z]([\+\-_\.][0-9a-zA-Z]+)*)+@(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]*\.)+[a-zA-Z0-9]{2,3})$",
  18. ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "EmailInvalid")]
  19. public string Email { get; set; }
  20.  
  21. [Display(Name = "Age", ResourceType = typeof(Resource))]
  22. [Required(ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "AgeRequired")]
  23. [Range(18, 60, ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "AgeRange")]
  24. public int Age { get; set; }
  25. }
  26. }

Step-4: Add an another class for Manage Languages property & function.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Class > Enter Class Name > Add.

  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 MvcMultilingual
  9. {
  10. public class SiteLanguages
  11. {
  12. public static List<Languages> AvailableLanguages = new List<Languages>
  13. {
  14. new Languages{ LangFullName = "English", LangCultureName = "en"},
  15. new Languages{ LangFullName = "Español", LangCultureName = "es"},
  16. new Languages{ LangFullName = "বাংলা", LangCultureName = "bn"}
  17. };
  18.  
  19. public static bool IsLanguageAvailable(string lang)
  20. {
  21. return AvailableLanguages.Where(a => a.LangCultureName.Equals(lang)).FirstOrDefault() != null ? true : false;
  22. }
  23.  
  24. public static string GetDefaultLanguage()
  25. {
  26. return AvailableLanguages[0].LangCultureName;
  27. }
  28.  
  29. public void SetLanguage(string lang)
  30. {
  31. try
  32. {
  33. if (!IsLanguageAvailable(lang))
  34. lang = GetDefaultLanguage();
  35. var cultureInfo = new CultureInfo(lang);
  36. Thread.CurrentThread.CurrentUICulture = cultureInfo;
  37. Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
  38. HttpCookie langCookie = new HttpCookie("culture", lang);
  39. langCookie.Expires = DateTime.Now.AddYears(1);
  40. HttpContext.Current.Response.Cookies.Add(langCookie);
  41.  
  42. }
  43. catch (Exception ex)
  44. {
  45.  
  46. }
  47. }
  48. }
  49.  
  50. public class Languages
  51. {
  52. public string LangFullName { get; set; }
  53. public string LangCultureName { get; set; }
  54. }
  55. }

Step-5: Add an another class (inherit Controller) Where we will override BeginExecuteCore.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > Class > Enter Class Name > Add.

Here I have added this for check & set language each time any request execute.

  1. using System;
  2. using System.Web;
  3. using System.Web.Mvc;
  4.  
  5. namespace MvcMultilingual
  6. {
  7. public class MyBaseController : Controller
  8. {
  9. // Here I have created this for execute each time any controller (inherit this) load
  10. protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
  11. {
  12. string lang = null;
  13. HttpCookie langCookie = Request.Cookies["culture"];
  14. if (langCookie != null)
  15. {
  16. lang = langCookie.Value;
  17. }
  18. else
  19. {
  20. var userLanguage = Request.UserLanguages;
  21. var userLang = userLanguage != null ? userLanguage[0] : "";
  22. if (userLang != "")
  23. {
  24. lang = userLang;
  25. }
  26. else
  27. {
  28. lang = SiteLanguages.GetDefaultLanguage();
  29. }
  30. }
  31.  
  32. new SiteLanguages().SetLanguage(lang);
  33.  
  34. return base.BeginExecuteCore(callback, state);
  35. }
  36. }
  37. }

Step-6: Add a new Controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.

Step-7: Add new action into your controller for Get Action method.

Here I have added "Index" Action into "Home" Controller. Please write this following code

  1. using System.Linq;
  2. using System.Web;
  3. using System.Web.Mvc;
  4.  
  5. namespace MvcMultilingual.Controllers
  6. {
  7. public class HomeController : MyBaseController
  8. {
  9. public ActionResult Index()
  10. {
  11. return View();
  12. }
  13. }
  14. }

Step-8: Add view for the Action & design.

Right Click on Action Method (here right click on form action) > Add View... > Enter View Name > Select View Engine (Razor) > Check "Create a strong-typed view" > Select your model class > Add.
[N:B:Please Rebuild solution before add view.] 
Complete View 
  1. @model MvcMultilingual.Models.RegistrationModel
  2. @{
  3. ViewBag.Title = MvcMultilingual.Resource.Register;
  4. }
  5.  
  6. <h2>@MvcMultilingual.Resource.Register</h2>
  7.  
  8. @using (Html.BeginForm()) {
  9. @Html.ValidationSummary(true)
  10.  
  11. <fieldset>
  12. <legend>@MvcMultilingual.Resource.Register</legend>
  13.  
  14. <div class="editor-label">
  15. @Html.LabelFor(model => model.FirstName)
  16. </div>
  17. <div class="editor-field">
  18. @Html.EditorFor(model => model.FirstName)
  19. @Html.ValidationMessageFor(model => model.FirstName)
  20. </div>
  21.  
  22. <div class="editor-label">
  23. @Html.LabelFor(model => model.LastName)
  24. </div>
  25. <div class="editor-field">
  26. @Html.EditorFor(model => model.LastName)
  27. @Html.ValidationMessageFor(model => model.LastName)
  28. </div>
  29.  
  30. <div class="editor-label">
  31. @Html.LabelFor(model => model.Email)
  32. </div>
  33. <div class="editor-field">
  34. @Html.EditorFor(model => model.Email)
  35. @Html.ValidationMessageFor(model => model.Email)
  36. </div>
  37.  
  38. <div class="editor-label">
  39. @Html.LabelFor(model => model.Age)
  40. </div>
  41. <div class="editor-field">
  42. @Html.EditorFor(model => model.Age)
  43. @Html.ValidationMessageFor(model => model.Age)
  44. </div>
  45.  
  46. <p>
  47. <input type="submit" value="@MvcMultilingual.Resource.Register" />
  48. </p>
  49. </fieldset>
  50. }
  51.  
  52.  
  53. @section Scripts {
  54. @Scripts.Render("~/bundles/jqueryval")
  55. }

Step-9: Add another action into your controller for POST Method

Here I have added "Index" Action into "HomeController" Controller for POST Action. Please write this following code

  1. [HttpPost]
  2. public ActionResult Index(RegistrationModel r)
  3. {
  4. return View(r);
  5. }

Step-10: Add another action into your controller for Change Language

Here I have added "ChangeLanguage" Action into "HomeController" Controller for Change Language. Please write this following code
Complete Layout Page 
  1. public ActionResult ChangeLanguage(string lang)
  2. {
  3. new SiteLanguages().SetLanguage(lang);
  4. return RedirectToAction("Index", "Home");
  5. }

Step-11: Modify Layout Page for Show Available Languages (Language Switcher).

Complete Layout Page 
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width" />
  6. <title>@ViewBag.Title</title>
  7. @Styles.Render("~/Content/css")
  8. @Scripts.Render("~/bundles/modernizr")
  9. </head>
  10. <body>
  11.  
  12. <div style="padding:5px">
  13. @* Here I will add Language Switcher *@
  14. @{
  15. foreach (var i in MvcMultilingual.SiteLanguages.AvailableLanguages)
  16. {
  17. @Html.ActionLink(i.LangFullName, "ChangeLanguage", "Home", new{lang = i.LangCultureName}, null) <text>&nbsp;</text>
  18. }
  19. }
  20. </div>
  21. @RenderBody()
  22. @Scripts.Render("~/bundles/jquery")
  23. @RenderSection("scripts", required: false)
  24. </body>
  25. </html>
Step-12: Run Application.

No comments:

Post a Comment

How to register multiple implementations of the same interface in Asp.Net Core?

 Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...