多語系採用資料庫處理。區分為系統多語系(table:LocaleStringResource) 及資料多語系(table:LocalizedProperty)。語系 (table:Language) , 一開始的確很難理解 所以直接忽略原理,後續理解它的原理有助於更多 .net core asp.net 的技術應用。

T

背景物件介紹 (HtmlString)

HtmlString Class 繼承自 IHtmlContent 目的是為了 wraps an HTML encoded String.
所以你要用字串在 razor 頁面上輸出 html 就得用 new Htmlstring 或 Html.Raw 不然直接輸出字串的話會是編碼過後字串, 而不是 html.

                @*這個在上面直接輸出 *@
                @(new HtmlString("<h1>SDF</h1>"))
        
                @* .Value 會編碼 html 後輸出, 所以 <h1></h1> 都會輸出 *@
                @(new HtmlString("<h1>new HtmlString(\"\")</h1>).Value</h1>").Value)
        
                @Html.Raw("<h2> Html.Raw 回傳的是一個 IHtmlContent 介面 所以與 new HtmlString(\"\" 是差不多的東西)</h2>")
            

LocalizedString 設計

                namespace Nop.Web.Framework.Localization
                {
                    /// <summary>
                    /// Localized string
                    /// </summary>
                    public class LocalizedString : HtmlString
                    {
                        /// <summary>
                        /// Ctor
                        /// </summary>
                        /// <param name="localized">Localized value</param>
                        public LocalizedString(string localized): base (localized)
                        {
                            Text = localized;
                        }
                        
                        /// <summary>
                        /// Text
                        /// </summary>
                        public string Text { get; }
                    }
                }
            

LocalizedString 繼承自 HtmlString , 而多了一個 Text 屬性

委派物件 Localizer

                /// <summary>
                /// Localizer
                /// </summary>
                /// <param name="text">Text</param>
                /// <param name="args">Arguments for text</param>
                /// <returns>Localized string</returns>
                public delegate LocalizedString Localizer(string text, params object[] args);
            

在 Razor Page 上的用法

下方的用法是在頁面上用屬性 T 回傳一個委派物件 Localizer , 讓 Localizer 回傳 LocalizedString 物件 (也就是 HtmlString 或 IHtmlContent) 與 @(new HtmlString("")) 是一樣的意思, 只不過它將回傳語系字串的處理包裝起來了.
                    private ILocalizationService _localizationService;
                    private Localizer _localizer;
            
                    /// <summary>
                    /// Get a localized resources
                    /// </summary>
                    public Localizer T
                    {
                        get
                        {
                            if (_localizationService == null)
                                _localizationService = EngineContext.Current.Resolve<ILocalizationService>();
            
                            if (_localizer == null)
                            {
                                _localizer = (f, args) =>
                                {
                                    var resFormat = _localizationService.GetResource(f);
                                    if (string.IsNullOrEmpty(resFormat))
                                    {
                                        return new LocalizedString(f);
                                    }
                                    return new LocalizedString((args == null || args.Length == 0)
                                        ? resFormat
                                        : string.Format(resFormat, args));
                                };
                            }
                            return _localizer;
                        }
                    }
            
以下的寫法改以function來處理, 效果一樣
                    private ILocalizationService _localizationService;
            
                    /// <summary>
                    /// Get a localized resources
                    /// </summary>
                    public LocalizedString T(string source, params object[] args)
                    {
            
                        if (_localizationService == null)
                            _localizationService = EngineContext.Current.Resolve<ILocalizationService>();
            
                        var resFormat = _localizationService.GetResource(source);
                        if (string.IsNullOrEmpty(resFormat))
                        {
                            return new LocalizedString(source);
                        }
            
                        return new LocalizedString((args == null || args.Length == 0)
                            ? resFormat
                            : string.Format(resFormat, args));
                    }
            

資料庫

Language

語言種類管理,可以設定多種語言,但相對應的就會有多語系的資料欄位要輸入,像如果你設三個語系, 商品欄位名字就會出現三個相對應的欄位讓你輸入

LocaleStringResource

語系資源檔,頁面上UI要顯示的語系資料。可以在語言管理下方匯出修改後再匯入。

LocalizedProperty

語系資源檔,資料用的語系資料。