ABP的語言切換


在ABP官網http://www.aspnetboilerplate.com/創建一個Multi Page Web Application項目並打開,在Web項目下可以找到一個Controllers/LayoutController.cs,里面有代碼如下:

        [ChildActionOnly]
        public PartialViewResult LanguageSelection()
        {
            var model = new LanguageSelectionViewModel
                        {
                            CurrentLanguage = _localizationManager.CurrentLanguage,
                            Languages = _localizationManager.GetAllLanguages()
                        };

            return PartialView("_LanguageSelection", model);
        }

對,這段控制器代碼對應於視圖Views/Layout/_LanguageSelection.cshtml,用於頁面右上角的語言切換:

控制器傳給視圖一個LanguageSelectionViewModel對象,用於展示當前默認使用的語言和下拉菜單中支持的語言。

觀察上面的代碼,就知道LanguageSelectionViewModel對象里的信息其實都是從LocalizationManager傳遞過來的。查看ABP的源碼,信息的源頭又可以追溯到ILocalizationConfiguration,原來,語言實際配置的代碼放在Web項目的App_Start/某某WebModule.cs的PreInitialize方法里:

       public override void PreInitialize()
        {
            //Add/remove languages for your application
            Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true));
            Configuration.Localization.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flag-tr"));
            Configuration.Localization.Languages.Add(new LanguageInfo("zh-CN", "簡體中文", "famfamfam-flag-cn"));

           ...
        }

LanguageInfo構造函數的第三個參數為圖標名,從_LanguageSelection視圖可以看到:

 <li><a href="/AbpLocalization/ChangeCulture?cultureName=@(language.Name)&returnUrl=@(Request.Url)"><i class="@language.Icon"></i> @language.DisplayName</a></li>

原來在這里使用了一組famfamfam國旗圖標,官網:http://www.famfamfam.com/lab/icons/flags/

查看Web項目下的Content/flags/famfamfam-flags.css可以看到對這些國旗圖標的定義:

[class^="famfamfam-flag"] {
  display: inline-block;
  width: 16px;
  height: 11px;
  line-height: 11px;
  /* vertical-align: text-top; */
  background-image: url("famfamfam-flags.png");
  background-position: 0 0;
  background-repeat: no-repeat;
}

.famfamfam-flag-zw { background-position: 0px 0px; width: 16px; height: 11px; }
.famfamfam-flag-zm { background-position: -16px 0px; width: 16px; height: 11px; }
.famfamfam-flag-za { background-position: 0px -11px; width: 16px; height: 11px; }
.famfamfam-flag-yt { background-position: -16px -11px; width: 16px; height: 11px; }
.famfamfam-flag-ye { background-position: -32px 0px; width: 16px; height: 11px; }
.famfamfam-flag-ws { background-position: -32px -11px; width: 16px; height: 11px; }
.famfamfam-flag-wf { background-position: 0px -22px; width: 16px; height: 11px; }
...

圖標文件:

當我們切換語言時,提交的鏈接大概是這樣的:

http://localhost:61754/AbpLocalization/ChangeCulture?cultureName=en&returnUrl=http://localhost:61754/

問題是,ChangeCulture控制器在哪?

查看ABP源碼,可以找到Abp.Web.Mvc.Controllers.Localization.AbpLocalizationController類:

    public class AbpLocalizationController : AbpController
    {
        [DisableAuditing]
        public virtual ActionResult ChangeCulture(string cultureName, string returnUrl = "")
        {
            if (!GlobalizationHelper.IsValidCultureCode(cultureName))
            {
                throw new AbpException("Unknown language: " + cultureName + ". It must be a valid culture!");
            }

            Response.Cookies.Add(new HttpCookie("Abp.Localization.CultureName", cultureName) { Expires = Clock.Now.AddYears(2) });

            if (Request.IsAjaxRequest())
            {
                return Json(new MvcAjaxResponse(), JsonRequestBehavior.AllowGet);
            }

            if (!string.IsNullOrWhiteSpace(returnUrl))
            {
                return Redirect(returnUrl);
            }

            return Redirect(Request.ApplicationPath);
        }
    }

一目了然,ABP把“當前所使用的語言”記錄在cookies里了。

再回頭翻查LocalizationManager類里定義的GetCurrentLanguage方法:

       private LanguageInfo GetCurrentLanguage()
        {
            if (_configuration.Languages.IsNullOrEmpty())
            {
                throw new AbpException("No language defined in this application. Define languages on startup configuration.");
            }

            var currentCultureName = Thread.CurrentThread.CurrentUICulture.Name;

            //Try to find exact match
            var currentLanguage = _configuration.Languages.FirstOrDefault(l => l.Name == currentCultureName);
            if (currentLanguage != null)
            {
                return currentLanguage;
            }

            //Try to find best match
            currentLanguage = _configuration.Languages.FirstOrDefault(l => currentCultureName.StartsWith(l.Name));
            if (currentLanguage != null)
            {
                return currentLanguage;
            }

            //Try to find default language
            currentLanguage = _configuration.Languages.FirstOrDefault(l => l.IsDefault);
            if (currentLanguage != null)
            {
                return currentLanguage;
            }

            //Get first one
            return _configuration.Languages[0];
        }

上面代碼並沒發現讀取cookies的操作,再翻到ABP源碼的Abp.Web.AbpWebApplication類,原來放到了Application_BeginRequest方法里讀取:

       protected virtual void Application_BeginRequest(object sender, EventArgs e)
        {
            var langCookie = Request.Cookies["Abp.Localization.CultureName"];
            if (langCookie != null && GlobalizationHelper.IsValidCultureCode(langCookie.Value))
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo(langCookie.Value);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(langCookie.Value);
            }
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM