使用類別庫儲存資源檔

by vivid 12. 十二月 2018 00:20

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:
N181220201
出刊日期: 2018/12/12

全球化(Globalization)是設計應用程式支援不同文化特性的程序。當地語系化(Localization)則是針對應用程式資源做本土化設計的過程,例如讓應用程式使用者介面上的文字,以特定文化的語系來做顯示。ASP.NET Core新增IStringLocalizer與IStringLocalizer<T>介面以開發當地語系化應用程式。為了讓開發方便,開發專案的早期,不需要使用資源檔來儲存特定文化特性要顯示的文字或圖片。

本文將介紹如何利用類別庫類型的專案來儲存資源檔,並在ASP.NET Core MVC應用程式之中使用資源檔設計當地語系化網站應用程式。

 

設計類別庫儲存資源檔案

我們先來建立類別庫專案以儲存資源檔。從Visual Studio開發工具「File」-「New」-「Project」項目,在「New Project」對話盒中,選取左方「Installed」清單-「Templates」-「Visual C#」程式語言,從「.NET Standard」分類中,選取「Class Library(.NET Standard) 」。請參考下圖所示,適當設定專案名稱,以及設定專案存放路徑,按下「OK」鍵。

clip_image002

圖 1:建立「Class Library(.NET Standard) 」類別庫專案。

預設類別庫專案中包含一個「Class1.cs」檔案,在檔案中定義一個「SharedMessageResource」類別,此類別主要是為資源檔案設定一個對應的類別,以便透過類別來存取資源檔案。

using System;

namespace MyLibrary
{
    public class SharedMessageResource
    {
    }
}

建立「Resources」資料夾。從Visual Studio 2017開發工具 -「Solution Explorer」視窗 – 類別庫專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「Resources」,目前畫面看起來如下圖所示:

clip_image004

圖 2:建立「Resources」資料夾。

建立美國語系資源檔案

本文將建立兩個共用資源檔來存放應用程式共用訊息,並提供美國與台灣語系。共用資源檔案檔名要對應到前文建立的類別名稱「SharedMessageResource」。再來共用資源檔案的命名要以文化特性結尾。美國語系文化特性代號為「en-US」;而台灣則是「zh-TW」。沒有以文化特性結尾的資源檔案,則代表預設資源檔,這是選擇性的檔案,不是必要的,通常視為備用(fallback)文化特性。

從「Solution Explorer」視窗 -「你的專案」-「Resources」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目。在「Add New Item」對話盒,選取「Visual C# Items」-「General」分類下的「Resource File」項目,然後在下方將「Name:」設定為「SharedMessageResource.en-US.resx」最後按下「Add」按鈕,請參考下圖所示:

clip_image006

圖 3:建立美國語系共用資源檔。

編輯「SharedMessageResource.en-US.resx」資源檔案,新增以下資料,注意視窗上方「Access Modifier」的設定為「No code generation」,目前資源檔的畫面看起來如下圖所示:

clip_image008

圖 4:編輯美國語系共用資源檔。

在「Solution Explorer」視窗,選取「SharedMessageResource.en-US.resx」檔案,按「CTRL+C」複製檔案,再選取「Resources」資料夾,按「CTRL+V」貼到資料夾,並將檔案名字改為「SharedMessageResource.zh-TW.resx」。編輯資源檔案,將「SayHi」與「SayBye」對應的Value換成以下資料,請參考下圖所示:

clip_image010

圖 5:編輯台灣語系共用資源檔。

完成後,目前類別庫專案中的檔案結構看起來如下圖所示:

clip_image012

圖 6:類別庫專案中的檔案結構。

選取Visual Studio開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。

建立ASP.NET Core Web Application

下一步讓我們在方案中加入一個ASP.NET Core Web Application。從Visual Studio開發工具「File」-「Add」-「New Project」項目,在「New Project」對話盒中,選取左方「Installed」清單-「Templates」-「Visual C#」程式語言,從「.NET Core」分類中,選取「ASP.NET Core Web Application」。請參考下圖所示,適當設定專案名稱,以及專案存放路徑,按下「OK」鍵。

clip_image014

圖 7:建立ASP.NET Core Web Application。

在「New ASP.NET Core Web Application」對話盒中,確認左上方的清單選取「.NET Core」,右上方的清單ASP.NET Core版本為「ASP.NET Core 2.1」,選取下方的「Web Application ( Model – View – Controller) 」樣版專案,清除勾選下方的「Enable Docker Support」核取方塊,確定右方的「Authentication」項目設定為「No Authentication」,然後按下「OK」按鈕建立專案,請參考下圖所示:

clip_image016

圖 8:建立「Web Application ( Model – View – Controller) 」樣版專案。

從「Solution Explorer」視窗 -「你的ASP.NET Core MVC Web Application專案」-資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「Reference」項目。在「Reference Manager」對話盒中,選取左方「Projects」-「Solution」,然後勾選右方的「MyLibrary」類別庫專案,請參考下圖所示:

clip_image018

圖 9:加入「MyLibrary」類別庫專案參考。

修改「Home Controller」類別程式碼如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MyWebApplication.Models;

using Microsoft.Extensions.Localization;
using MyLibrary;
using Microsoft.AspNetCore.Localization;

namespace MyWebApplication.Controllers
{
    public class HomeController : Controller
    {
        private readonly IStringLocalizer<SharedMessageResource> _localizer;
        public HomeController( IStringLocalizer<SharedMessageResource> localizer )
        {
            _localizer = localizer;
        }

        public IActionResult Index( )
        {
            IRequestCultureFeature rcf = HttpContext.Features.Get<IRequestCultureFeature>();
            ViewBag.provider = rcf?.Provider?.GetType().Name;

            ViewBag.msg1 = _localizer["SayHi"];
            ViewBag.msg2 = _localizer["SayBye"];

            return View();
        }

        [ResponseCache( Duration = 0, Location = ResponseCacheLocation.None, NoStore = true )]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

 

先引用以下命名空間:

using Microsoft.Extensions.Localization;

using MyLibrary;

using Microsoft.AspNetCore.Localization;

在「Home Controller」類別階層宣告一個唯讀變數,型別為「IStringLocalizer< SharedMessageResource>」:

 

private readonly IStringLocalizer<SharedMessageResource> _localizer;

在「Home Controller」類別加入一個建構函式,以建構函式注入方式,傳入「IStringLocalizer< SharedMessageResource >」型別的localizer物件,並將傳入的「localizer」指定給「_localizer」變數:

 

public HomeController( IStringLocalizer<SharedMessageResource> localizer )
{
            _localizer = localizer;
}

 

修改「Home Controller」類別「Index」方法中的程式碼,然後在「Index」方法,加入以下程式碼,取出資源檔案中儲存的當地語系化字串:

public IActionResult Index()
        {
            IRequestCultureFeature rcf = HttpContext.Features.Get<IRequestCultureFeature>();
            ViewBag.provider = rcf?.Provider?.GetType().Name;

            ViewBag.msg1 = _localizer["SayHi"];
            ViewBag.msg2 = _localizer["SayBye"];

            return View();
        }

 

此外,我們使用HttpContext.Features.Get<IRequestCultureFeature>( )方法取得IRequestCultureFeature,來取得目前程式套用的是哪一個當地語系化提供者(default providers)。預設ASP.NET Core提供預設當地語系化提供者(default providers)包含以下三種:

· QueryStringRequestCultureProvider

· CookieRequestCultureProvider

· AcceptLanguageHeaderRequestCultureProvider

套用的順序根據表列清單由上至下優先權由高到低,順序可以客製化調整,若找不到適當的提供者,則會採用預設文化特性(DefaultRequestCulture)。

建立「Index」檢視

下一步驟,建立「Index」檢視。將游標停留在控制器程式設計畫面「Index」方法之中,按滑鼠右鍵,從快捷選單選取「Add View」。在「Add View」對話盒中,設定:

· View name:「Index」。

· Template:「Empty (without model)」。

· Model class:不設定。

· 清除勾選所有核取方塊。

然後按下「Add」按鈕。Visual Studio 2017便會在「Views\Home」資料夾下,新增一個「Index.cshtml」檔案,請參考下圖所示:

clip_image020

圖 10:建立「Index」檢視。

修改Index檢視的內容。從「Solution Explorer」視窗專案名稱下,雙擊「Views\Home\Index.cshtml」檔案,開啟設計畫面,在<body>下<div>標籤中,新增以下標籤,顯示當地語系化字串:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    Provider : @ViewBag.provider
    <br />
    @ViewBag.msg1
    <br />
    @ViewBag.msg2
</body>
</html>


 

啟用當地語系化

修改「Startup」類別,在「ConfigureServices」方法加入以下程式碼,叫用「AddLocalization」方法,加入當地語系化服務,傳入「LocalizationOptions」物件當參數以設定「ResourcesPath」,指定資源檔案所在的資料夾為「Resources」:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace MyWebApplication
{
    public class Startup
    {
        public Startup( IConfiguration configuration )
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices( IServiceCollection services )
        {
            services.AddLocalization( options => options.ResourcesPath = "Resources" );

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddMvc().SetCompatibilityVersion( CompatibilityVersion.Version_2_1 );
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler( "/Home/Error" );
                app.UseHsts();
            }
            var supportedCultures = new[] {
                new CultureInfo( "en-US" ),
                new CultureInfo( "zh-TW" )
            };

            app.UseRequestLocalization( new RequestLocalizationOptions
            {
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            });

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

 

修改「Configure」方法,叫用「UseRequestLocalization」方法來使用服務,並利用「RequestLocalizationOptions」物件,設定支援美國(en-US)與台灣(zh-TW)兩種文化特性。

選取Visual Studio開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:上列的埠號可能會依據實際上的操作而有所不同,請修改為實際的埠號),然後在瀏覽器輸入以下網址(URL)

https://localhost:44329/home/Index

根據瀏覽器語言喜號設定的不同,你的執行結果可能會有不同。以筆者的測試環境而言,作業系統是英文版,使用Chrome瀏覽器測試,語言喜好設定最喜好語言設為「English (United States)」,請參考下圖所示:

clip_image022

圖 11:Chrome瀏覽器測試,語言喜好設定。

目前執行結果如下圖所示,套用「AcceptLanguageHeaderRequestCultureProvider」,並顯示出美國語系資源檔中的文字:

clip_image024

圖 12:執行結果。

由於「QueryStringRequestCultureProvider 」優先權高於「AcceptLanguageHeaderRequestCultureProvider」,修改瀏覽器網址測試,使用查詢字串指定文化特性是美國:

https://localhost:44329/?culture=en-US

執行的結果如下圖所示:

clip_image026

圖 13:使用查詢字串指定文化特性測試。

修改瀏覽器網址測試,使用查詢字串指定文化特性是台灣:

https://localhost:44329/?culture=zh-tw

執行的結果如下圖所示:

clip_image028

圖 14:使用查詢字串指定文化特性測試。

修改瀏覽器網址測試,使用查詢字串指定文化特性是目前應用程式不支援的日本:

https://localhost:44329/?culture=ja-jp

執行的結果如下圖所示,可能會與您的環境DefaultRequestCulture設定不同而結果不同。因為查詢字串指定不支援的日本文化特性「ja-JP」,因此這次是套用「AcceptLanguageHeaderRequestCultureProvider」:

clip_image030

圖 15:使用查詢字串指定文化特性測試。

文化特性備用(Culture fallback)

資源檔案名稱沒有後綴文化特性稱之為預設資源檔案,以提供文化特性備用(Culture fallback)功能。我們來測試一下它的用法。先刪除「MyLibrary」專案中的「SharedMessageResource.en-US.resx」檔案,然後加入一個新的資源檔案,命名為「SharedMessageResource.resx」。編輯其中的內容如下圖所示:

clip_image032

圖 16:預設資源檔案。

目前專案中的檔案結構看起來如下圖所示:

clip_image034

圖 17:類別庫檔案結構。

修改瀏覽器網址測試,根據瀏覽器語言喜好設定的不同,你的執行結果可能會有不同。以筆者的測試環境而言,作業系統是英文版,使用Chrome瀏覽器測試,語言喜好設定最喜好語言設為「English (United States)」,請參考下圖所示:

https://localhost:44329/home/index

執行結果如下,套用「AcceptLanguageHeaderRequestCultureProvider」,並顯示出預設資源檔中的文字,請參考下圖所示:

clip_image036

圖 18:預設資源檔套用測試。

修改瀏覽器網址測試,使用查詢字串指定文化特性是美國:

https://localhost:44329/?culture=en-US

執行的結果如下圖所示,顯示出預設資源檔中的文字:

clip_image038

圖 19:預設資源檔套用測試。

使用查詢字串指定文化特性是目前應用程式不支援的日本文化特性:

https://localhost:44329/?culture=ja-jp

執行的結果如下圖所示,顯示出預設資源檔中的文字,請參考下圖所示:

clip_image040

圖 20:預設資源檔套用測試。

修改瀏覽器網址測試,使用查詢字串指定文化特性是台灣:

https://localhost:44329/?culture=zh-tw

執行的結果,請參考下圖所示:

clip_image042

圖 21:預設資源檔套用測試。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET Core MVC | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List