本文轉自: https://blog.csdn.net/Cooldiok/article/details/7831351 2017年10月22日 21:31:22 Cooldiok 微軟作為ASP.NET的創造者,它對於官網的結構設計肯定有值得我們借鑒和參考的地方 本項目是基於VS2017 pro開 ...
本文轉自: https://blog.csdn.net/Cooldiok/article/details/7831351
2017年10月22日 21:31:22 Cooldiok
微軟作為ASP.NET的創造者,它對於官網的結構設計肯定有值得我們借鑒和參考的地方
本項目是基於VS2017 pro開發的,將從你已經創建了一個MVC項目開始介紹:
流程圖
1.創建語言文件
創建App_GlobalResources文件夾
創建Language文件夾
創建資源文件
這些操作做完後,目錄結構應該是以下這樣的
我們打開每個資源文件,在裡面添加一條TiTle數據
我推薦使用ResX Manager來管理語言文件
比如我已經創建了中文、英語、日語這三個語言文件,我如果要做修改的話就需要每個文件輪流修改,使用ResX Manager就能直接同時修改這三個語言文件,它還提供語言翻譯功能。具體使用方法與此文無關,就不再贅述了。
2.創建一個過濾器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 namespace MvcEdu.Filters 2 { 3 public class LocalizationAttribute : ActionFilterAttribute 4 { 5 public override void OnActionExecuting(ActionExecutingContext filterContext) 6 { 7 8 bool isSkipLocalization = filterContext.ActionDescriptor.IsDefined(typeof(WithoutLocalizationAttribute), inherit: true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(WithoutLocalizationAttribute), inherit: true); 9 10 if (!isSkipLocalization) 11 { 12 if (filterContext.RouteData.Values["lang"] != null && !string.IsNullOrWhiteSpace(filterContext.RouteData.Values["lang"].ToString())) 13 { 14 ///從路由數據(url)里設置語言 15 var lang = filterContext.RouteData.Values["lang"].ToString(); 16 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang); 17 } 18 else 19 { 20 ///從cookie里讀取語言設置 21 var cookie = filterContext.HttpContext.Request.Cookies["Localization.CurrentUICulture"]; 22 var langHeader = string.Empty; 23 if (cookie != null && cookie.Value != "") 24 { 25 ///根據cookie設置語言 26 langHeader = cookie.Value; 27 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader); 28 } 29 else 30 { 31 ///如果讀取cookie失敗則設置預設語言 32 langHeader = filterContext.HttpContext.Request.UserLanguages[0]; 33 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader); 34 } 35 ///把語言值設置到路由值里 36 filterContext.RouteData.Values["lang"] = langHeader; 37 //如果url中不包含語言設置則重定向到包含語言值設置的url里 38 string ReturnUrl = $"/{filterContext.RouteData.Values["lang"]}/{filterContext.RouteData.Values["controller"]}/{filterContext.RouteData.Values["action"]}"; 39 filterContext.Result = new RedirectResult(ReturnUrl); 40 } 41 42 /// 把設置保存進cookie 43 HttpCookie _cookie = new HttpCookie("Localization.CurrentUICulture", Thread.CurrentThread.CurrentUICulture.Name); 44 _cookie.Expires = DateTime.Now.AddYears(1); 45 filterContext.HttpContext.Response.SetCookie(_cookie); 46 47 base.OnActionExecuting(filterContext); 48 } 49 50 } 51 } 52 53 public class WithoutLocalizationAttribute : Attribute 54 { 55 } 56 }View Code
3.配置路由文件
我這邊因為只有三個語言文件,所以我對於語言項的輸入做了限制。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 namespace MvcEdu 2 { 3 public class RouteConfig 4 { 5 public static void RegisterRoutes(RouteCollection routes) 6 { 7 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 8 9 routes.MapRoute( 10 name: "Localization", // 路由名稱 11 url: "{lang}/{controller}/{action}/{id}", // 帶有參數的 URL\ 12 constraints: new { lang = "zh-CN|en-US|ja-JP" }, //限制可輸入的語言項 13 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }//參數預設值 14 ); 15 16 routes.MapRoute( 17 name: "Default", 18 url: "{controller}/{action}/{id}", 19 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 ); 21 } 22 } 23 }View Code
4.修改HomeController.cs文件,添加修改語言函數
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 namespace MvcEdu.Controllers 2 { 3 [Localization] //HomeController里的函數都要走Localization過濾器 4 public class HomeController : Controller 5 { 6 public ActionResult Index() 7 { 8 ViewBag.Title = Resources.Language.Title;//頁面中的Title值取語言文件里的Title值 9 return View(); 10 } 11 12 public ActionResult About() 13 { 14 ViewBag.Title = Resources.Language.Title;//頁面中的Title值取語言文件里的Title值 15 ViewBag.Message = "Your application description page."; 16 17 return View(); 18 } 19 20 public ActionResult Contact() 21 { 22 ViewBag.Title = Resources.Language.Title;//頁面中的Title值取語言文件里的Title值 23 ViewBag.Message = "Your contact page."; 24 25 return View(); 26 } 27 [WithoutLocalization]//這個函數不走Localization過濾器 28 public ActionResult ChangeLanguage(String NewLang, String ReturnUrl) 29 { 30 if (!ReturnUrl.EndsWith("/")) 31 { 32 ReturnUrl += "/"; 33 } 34 //use NewLang replace old lang,include input judgment 35 if (!string.IsNullOrEmpty(ReturnUrl) && ReturnUrl.Length > 3 && ReturnUrl.StartsWith("/") && ReturnUrl.IndexOf("/", 1) > 0 && new string[] { "zh-CN", "en-US","ja-JP" }.Contains(ReturnUrl.Substring(1, ReturnUrl.IndexOf("/", 1) - 1))) 36 { 37 ReturnUrl = $"/{NewLang}{ReturnUrl.Substring(ReturnUrl.IndexOf("/", 1))}"; 38 } 39 else 40 { 41 ReturnUrl = $"/{NewLang}{ReturnUrl}"; 42 } 43 return Redirect(ReturnUrl);//redirect to new url 44 } 45 } 46 }View Code
註意:我在使用vs2015 express for web時,出現了使用Resources.Language時智能提示沒出現Title的情況,此時去找一下Language.designer.cs里有無以下代碼,如果沒有的話則以後添加鍵值對的時候你們都要在此手動添加,或者把Language文件夾建在Controllers的同級目錄下然後再新建資源文件等操作也能解決該問題。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 查找類似 標題 的本地化字元串。 3 /// </summary> 4 internal static string Title { 5 get { 6 return ResourceManager.GetString("Title", resourceCulture); 7 } 8 }View Code
5.修改母版頁,添加了修改語言的link
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <div class="navbar-collapse collapse"> 2 <ul class="nav navbar-nav"> 3 <li>@Html.ActionLink("主頁", "Index", "Home")</li> 4 <li>@Html.ActionLink("關於", "About", "Home")</li> 5 <li>@Html.ActionLink("聯繫方式", "Contact", "Home")</li> 6 @*以下是添加的內容*@ 7 <li>@Html.ActionLink("en-US", "ChangeLanguage", "Home",new { NewLang = "en-US",ReturnUrl=Request.RawUrl},new { @class="testclass"})</li> 8 <li>@Html.ActionLink("zh-CN", "ChangeLanguage", "Home", new { NewLang = "zh-CN", ReturnUrl = Request.RawUrl }, new { @class = "testclass" })</li> 9 <li>@Html.ActionLink("ja-JP", "ChangeLanguage", "Home", new { NewLang = "ja-JP", ReturnUrl = Request.RawUrl }, new { @class = "testclass" })</li> 10 </ul> 11 </div>View Code
6.Views/Home的三個頁面我都加了顯示ViewBag.Title值的代碼
1 <h2>@ViewBag.Title.</h2>
7.現在我們來運行,看一下效果
首次登錄的時候因為url是localhost:50062/,沒有語言項,所以讀取瀏覽器預設語言“zh-CN”,然後重定向。
以下是點擊導航欄的en-US和ja-JP時的情況
8.如果用戶直接輸入http://localhost:50062/Home/Index/
程式會重定向到http://localhost:50062/cookie里保存的語言項OR瀏覽器預設語言/Home/Index/
基本做到了和MSDN效果一樣。
本文Demo下載:
本文參考了:
http://www.cnblogs.com/zoro-zero/p/6674442.html
http://www.cnblogs.com/CameronWu/p/5709442.html