本文轉自: https://blog.csdn.net/Cooldiok/article/details/7831351 html
2017年10月22日 21:31:22 Cooldiok web
微軟做爲ASP.NET的創造者,它對於官網的結構設計確定有值得咱們借鑑和參考的地方express
本項目是基於VS2017 pro開發的,將從你已經建立了一個MVC項目開始介紹:
流程圖
瀏覽器
1.建立語言文件
建立App_GlobalResources文件夾
cookie
建立Language文件夾
app
建立資源文件
ide
這些操做作完後,目錄結構應該是如下這樣的
函數
咱們打開每一個資源文件,在裏面添加一條TiTle數據
url
我推薦使用ResX Manager來管理語言文件
好比我已經建立了中文、英語、日語這三個語言文件,我若是要作修改的話就須要每一個文件輪流修改,使用ResX Manager就能直接同時修改這三個語言文件,它還提供語言翻譯功能。具體使用方法與此文無關,就再也不贅述了。
spa
2.建立一個過濾器
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 }
3.配置路由文件
我這邊由於只有三個語言文件,因此我對於語言項的輸入作了限制。
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 }
4.修改HomeController.cs文件,添加修改語言函數
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 }
注意:我在使用vs2015 express for web時,出現了使用Resources.Language時智能提示沒出現Title的狀況,此時去找一下Language.designer.cs裏有無如下代碼,若是沒有的話則之後添加鍵值對的時候大家都要在此手動添加,或者把Language文件夾建在Controllers的同級目錄下而後再新建資源文件等操做也能解決該問題。
1 /// <summary> 2 /// 查找相似 標題 的本地化字符串。 3 /// </summary> 4 internal static string Title { 5 get { 6 return ResourceManager.GetString("Title", resourceCulture); 7 } 8 }
5.修改母版頁,添加了修改語言的link
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>
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