1. 程式人生 > >ASP.NET MVC多語言 仿微軟網站效果

ASP.NET MVC多語言 仿微軟網站效果

string ride oca https net .cn 流程 exp att

文章轉載自:https://blog.csdn.net/cooldiok/article/details/78313513

微軟作為ASP.NET的創造者,它對於官網的結構設計肯定有值得我們借鑒和參考的地方

本項目是基於VS2017 pro開發的,將從你已經創建了一個MVC項目開始介紹:
流程圖
技術分享圖片

1.創建語言文件


創建App_GlobalResources文件夾


技術分享圖片

創建Language文件夾


技術分享圖片

創建資源文件


技術分享圖片

這些操作做完後,目錄結構應該是以下這樣的


技術分享圖片

我們打開每個資源文件,在裏面添加一條TiTle數據
技術分享圖片

我推薦使用ResXManager來管理語言文件

ResxManager:資源文件編輯工具,這個工具可以在一個界面中編輯所有語言的內容。 可以新增、刪除key。 註意:如果是新建的Resx,一定要有一個key之後才可以編輯。

下載地址:

單獨程序:http://resxmanager.com/

vs插件: https://marketplace.visualstudio.com/items?itemName=TomEnglert.ResXManager

比如我已經創建了中文、英語、日語這三個語言文件,我如果要做修改的話就需要每個文件輪流修改,使用ResX Manager就能直接同時修改這三個語言文件,它還提供語言翻譯功能。具體使用方法與此文無關,就不再贅述了。


技術分享圖片

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的同級目錄下然後再新建資源文件等操作也能解決該問題。

        /// <summary>
        ///  查找類似 標題 的本地化字符串。
        /// </summary>
        internal static string Title {
            get {
                return ResourceManager.GetString("Title", resourceCulture);
            }
        }


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值的代碼

<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效果一樣。

本文參考了:

http://www.cnblogs.com/zoro-zero/p/6674442.html
http://www.cnblogs.com/CameronWu/p/5709442.html

ASP.NET MVC多語言 仿微軟網站效果