如果你的網站需要被世界各地的人訪問,訪問者會使用各種不同的語言和文字書寫習慣,那么創建一個支持多語言的網站就是十分必要的了,這一篇文章就講述怎么快速合理的創建網站對多語言的支持。接下來通過一個實例來講述實踐方式。
首先創建一個ASP.NET MVC5應用程序,命名為Internationalization:
然后在Models中添加一個示例的模型類:
public class Employee { [Display(Name = "Name", ResourceType = typeof(Resources.Resource))] [Required(ErrorMessageResourceType = typeof(Resources.Resource), ErrorMessageResourceName = "NameRequired")] public string Name { get; set; } }
這里提到了Resources.Resource命名空間,接下來就創建它:
這是一個單獨的項目,用來存放各種語言的資源文件,我們創建了三個資源文件,分別存放了中文(默認)、英文和阿拉伯文,資源文件中存放了如下資源項:
注意:這里的資源因為需要在項目外部使用,所以需要將訪問修飾符修改為Public
接下來就是如何來確定訪問者要使用的語言了,在每個請求中,都會有一個Accept-language的頭,其中定義了可接受的語言類型,但是我們僅可以從它來判斷瀏覽器中設置的語言,而這個語言類型可能並不是訪問者實際需要的語言類型,所以,我們將設計一個可供選擇的語言列表,然后在服務器端使用發回Cookie的方式保存瀏覽器端實際需要的語言。
首先需要創建一個CultureHelper類,這個類的功能就是來判斷訪問者實際需要的語言類型:
public class CultureHelper { private static readonly List<string> validCultures = new List<string>() { "zh-cn", "en-us","ar" }; private static readonly List<string> cultures = new List<string>() { "zh-cn", "en-us","ar" }; public static bool IsRightToLeft() { return Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft; } public static string GetImplementedCulture(string name) { if (string.IsNullOrEmpty(name)) { return GetDefaultCulture(); } if (!validCultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Any()) { return GetDefaultCulture(); } if (cultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Any()) { return name; } var n = GetNeutralCulture(name); foreach (var c in cultures) { if (c.StartsWith(n)) { return c; } } return GetDefaultCulture(); } public static string GetDefaultCulture() { return cultures[0]; } public static string GetCurrentCulture() { return Thread.CurrentThread.CurrentCulture.Name; } public static string GetCurrentNeutralCulture() { return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name); } public static string GetNeutralCulture(string name) { if (!name.Contains("-")) { return name; } else { return name.Split('-')[0]; } } }
接下來創建一個BaseController類,並且確保之后創建的所有控制器繼承自它:
public class BaseController : Controller { protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) { string cultureName = string.Empty; HttpCookie cultureCookie = Request.Cookies["_culture"]; if (cultureCookie != null) { cultureName = cultureCookie.Value; } else { cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages[0] : null; } cultureName = CultureHelper.GetImplementedCulture(cultureName); Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureName); Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; return base.BeginExecuteCore(callback,state); } }
創建一個EmployeeController,作為多語言實踐的一個示例:
public class EmployeeController : BaseController { // // GET: /User/ public ActionResult Index() { return View(); } public ActionResult SetCulture(string culture) { culture = CultureHelper.GetImplementedCulture(culture); HttpCookie cookie = Request.Cookies["_culture"]; if (cookie != null) { cookie.Value = culture; } else { cookie = new HttpCookie("_culture"); cookie.Value = culture; cookie.Expires = DateTime.Now.AddDays(1); } Response.Cookies.Add(cookie); return RedirectToAction("Index"); } }
在程序包管理控制台中,使用PS命令,安裝Bootstrap對RightToLeft文字習慣的支持:
Install-Package Twitter.Bootstrap.RTL
然后在App_Start中的BundleConfig.cs中添加兩個資源文字的虛擬捆綁路徑:
bundles.Add(new ScriptBundle("~/bundles/bootstrap-rtl").Include( "~/Scripts/bootstrap-rtl.js", "~/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css-rtl").Include( "~/Content/css/bootstrap-rtl.css", "~/Content/site.css"));
最后,創建Index視圖:
@model Internationalization.Models.Employee @{ ViewBag.Title = "Index"; var culture = System.Threading.Thread.CurrentThread.CurrentCulture.Name.ToLowerInvariant(); } @helper selected(string c, string culture) { if (c == culture) { @:checked="checked" } } @*選擇語言列表*@ @using (Html.BeginForm("SetCulture", "Employee")) { <fieldset> <legend></legend> <div class="control-group"> <div class=" "> <label for="zh-cn"> <input name="culture" id="zh-cn" value="zh-cn" type="radio" @selected("zh-cn", culture) /> 中文 </label> </div> </div> <div class="control-group"> <div class="controls"> <label for="en-us"> <input name="culture" id="en-us" value="en-us" type="radio" @selected("en-us", culture) /> English </label> </div> </div> <div class="control-group"> <div class="controls"> <label for="en-us"> <input name="culture" id="ar" value="ar" type="radio" @selected("ar", culture) /> عربي </label> </div> </div> </fieldset> } @*創建員工表單*@ @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h2>@Resources.Resource.AddEmployee</h2> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } @*在選擇語言后,自動提交*@ @section Scripts { @Scripts.Render("~/bundles/jqueryval") <script type="text/javascript"> (function ($) { $("input[type = 'radio']").click(function () { $(this).parents("form").submit(); // post form }); })(jQuery); </script> }
還需要更改_Layout.cshtml文件,當文字習慣為右到左時,需要切換bootstrap的樣式文件:
<!DOCTYPE html> <html lang="@Internationalization.Helpers.CultureHelper.GetCurrentNeutralCulture()" dir="@(Internationalization.Helpers.CultureHelper.IsRightToLeft() ? "rtl" : "ltr")"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - 我的 ASP.NET 應用程序</title> @Styles.Render("~/Content/css" + (Internationalization.Helpers.CultureHelper.IsRightToLeft() ? "-rtl" : "")) @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("應用程序名稱", "Index", "Home", null, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("主頁", "Index", "Home")</li> <li>@Html.ActionLink("關於", "About", "Home")</li> <li>@Html.ActionLink("聯系方式", "Contact", "Home")</li> </ul> </div> </div> </div> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - 我的 ASP.NET 應用程序</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap" + (Internationalization.Helpers.CultureHelper.IsRightToLeft() ? "-rtl" : "")) @RenderSection("scripts", required: false) </body> </html>
演示效果:
最終DEMO地址:點擊這里,感謝園友支持,這一期會一直進行下去的
如果您覺得這篇文章對您有用,勞煩給個贊!
如果您覺得這篇文章可能對別人游泳,勞煩您推薦一個!