介紹
開發多語言支持的ASP.NET Core 2.x Web應用程序需要大量的基礎架構設置,並且耗費時間和精力。這篇文章,我們將使用LazZiya.ExpressLocalization nuget包一步本地化支持。
背景
大多數網絡應用程序都是基於網址的本地化。因此我們可以在網址中看到所選的語言。例如http://www.example.com/en/Contact。不幸的是,ASP.NET Core 僅提供一下請求語言程序。
- QueryStringRequestCultureProvider
- CookieRequestCultureProvider
- AcceptLanguageHeaderRequestCultureProvider
爲了實現路由值本地化,我們需要構建自定義本地化程序並定義全局路由模版。基本上,我們需要完成一下本地化步驟才能擁有完全本地化的Web應用程序。
- Build route value request culture provider
- Define global route template for culture parameter
- Setup DataAnnotations localization
- Setup ModelBinding error messages localization
- Setup identity describer error messsages
- Setup view localization
- Setup client side validation scripts for validating localized number, dates, etc.
- Provide localized resources for each part
所有這些步驟都需要耗費大量工作和時間。因此,使用LazZiya.ExpressLocalization包的好處就是通過簡單的代碼消除在本地化設置方面耗費的時間和精力。
創建工程
讓我們創建一個基於ASP.NET Core 2.2 的Web應用程序(我使用的是VS 2019)
- 創建一個新工程,選擇ASP.NET Core Web Application.
- 點擊下一步,給工程一個友好的名稱,點擊創建
- 選擇Web應用程序,並確保將身份驗證更改爲個人用戶賬戶
- 點擊創建,等待解決方案創建完成。完成後,可以通過解決方案資源管理器中選擇項目名稱來執行測試運行,然後按(CTRL+B)構建項目,按(CTRL+W)在瀏覽器中運行,而不是調試。
安裝 LazZiya.ExpressLocalization
- 在項目名稱下的解決方案資源管理器中,右鍵單擊Dependencies並選擇Manage Nuget Packages
- 轉到Browse選項卡,並搜索LazZiya,選擇LazZiya.ExpressLocalization,點擊Install,選擇最新版本(寫這篇文章是最新版本爲v1.1.1)
- 它將要求安裝兩個軟件包,點擊OK,等待安裝完成
- LazZiya.ExpressLocalization (required for all localization setup)
- LazZiya.TagHelpers (required for client side localization validation and language dropdown)
創建本地化資源
我已經爲項目準備了本地化資源,因此你不必郎芬時間來創建本地化資源。
在項目根路徑創建一個新文件夾命名爲“LocalizationResources”
在LocalizationResources文件夾下,創建個public類, 名稱爲“ViewLocalizationResource”,這個類將用於對資源文件進行分組已進行視圖本地化。
namespace ExpressLocalizationSample.LocalizationResources
{
public class ViewLocalizationResource
{
}
}
在LocalizationResources 文件夾下創建public類,名稱爲“ExpressLocalizationResource”,此類用於對identity,模型綁定(model binding)和數據註解(data annotation)的分組資源文件。
namespace ExpressLocalizationSample.LocalizationResources
{
public class ExpressLocalizationResource
{
}
}
我們將使用這兩個類將資源類型傳遞個快速本地化方法。
最後,從此存儲庫文件夾下載先關的語言資源文件。請注意,你需要爲每種語言下載兩個文件,例如ExpressLocalizationResource.tr.resx 和ViewLocalizationResource.tr.resx。複製下載的文件到LocalizationResources文件夾
在代碼中使用
最後,我們已經準備好進行本地化設置了。
打開startup.cs文件並添加所需的語言列表,然後添加一步本地化設置,
var cultures = new[]
{
new CultureInfo("tr"),
new CultureInfo("ar"),
new CultureInfo("hi"),
new CultureInfo("en"),
};
services.AddMvc()
.AddExpressLocalization<ExpressLocalizationResource, ViewLocalizationResource>(
ops =>
{
ops.ResourcesPath = "LocalizationResources";
ops.RequestLocalizationOptions = o =>
{
o.SupportedCultures = cultures;
o.SupportedUICultures = cultures;
o.DefaultRequestCulture = new RequestCulture("en");
};
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
然後在Configure方法下,配置應用程序以使用請求本地化
app.UseRequestLocalization();
添加語言導航
在Pages文件夾下,打開_ViewImports.cshtml文件,並添加LazZiya.TagHelpers,這個有助於創建語言導航。
@using LazZiya.TagHelpers
@addTagHelper *, LazZiya.TagHelpers
打開Pages/Shared/_Layout.cshtml文件,並在_LoginPartial 標籤添加語言導航標籤。
<partial name="_LoginPartial" />
<language-nav view-context="ViewContext"></language-nav>
LanguageNav有一個必須的參數“view-context”。可以查閱有關LanguageNav tag helper資源。
我們進行第一次運行:
運行的很好,到目前爲止我們的導航支持多語言,但我們仍然需要本地化視圖已查看本地化版本。
本地化視圖
已下載的“ViewLocalizationResource.xx.resx”文件中已提供默認項目的本地化文本,如果需要爲視圖添加更多自定義文本,需要將它們添加到“ViewLocalizationResource.xx.resx”文件中。
打開Pages/_ViewImport.cshtml文件並注入SharedCultureLocalizer,需要引用ExpressLocalization。
@using LazZiya.ExpressLocalization
@inject SharedCultureLocalizer _loc
然後打開Pages/Index.cshtml並使用文本本地化方法。
@page
@model IndexModel
@{
ViewData["Title"] = _loc.Text("Home page");
}
<div class="text-center">
<h1 class="display-4">@_loc.Text("Welcome")</h1>
<p>@_loc.Text("Learn about
<a href='https://docs.microsoft.com/aspnet/core'>
building Web apps with ASP.NET Core</a>").</p>
</div>
使用相同的過程來本地化其他視圖中的所有文本。
本地化URLs
雖然頁面處理默認的語言中,但是如果點擊Privacy,Login,Reigster鏈接,將會注意到我們丟失了所選的語言,這是因爲我們未將語言路由值添加到鏈接中。
打開Pages/Index.cshtml文件,添加System.Globalization的引用
@using System.Globalization
然後打開Pages/_LoginPartial.cshtml文件,在頁面頂部添加一個culture參數
@{
var culture = CultureInfo.CurrentCulture.Name;
}
使用此參數爲所有鏈接提供語言路由值,
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register"
asp-route-culture="@culture">@_loc.Text("Register")</a>
對項目中所有的視圖執行此操作。
本地化身份驗證視圖
諸如登錄、註冊、和配置文件等相關Identity進行搭建後才能進行修改。
右鍵點擊項目名稱,選擇Add --> New Scaffolded Item…
選擇Identity,並點擊Add
選擇Override all files,並選擇ApplicationDbContext
點擊Addhou,將創建一個新的域文件夾,包括所有與Identity相關的視圖
Identity域包括三個_ViewImports文件夾:
- Areas/Identity/Pages/_ViewImports.cshtml
- Areas/Identity/Pages/Account/_ViewImports.cshtml
- Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml
像以前對Pages/_ViewImports.cshtml所做的那樣,將以下代碼添加到所有的這些文件中
@using System.Globalization
@using LazZiya.TagHelpers
@addTagHelper *, LazZiya.TagHelpers
@using LazZiya.ExpressLocalization
@inject SharedCultureLocalizer _loc
像以前一樣,瀏覽修改裏面的視圖文件並添加上語言路徑參數,以下是對Register.cshtml頁面的修改
@page
@model RegisterModel
@{
ViewData["Title"] = _loc.Text("Register");
var culture = CultureInfo.CurrentCulture.Name;
}
<h1>@ViewData["Title"]</h1>
<div class="row">
<div class="col-md-4">
<form asp-route-returnUrl="@Model.ReturnUrl"
method="post" asp-route-culture="@culture">
<h4>@_loc.Text("Create a new account").</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email"
class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password"
class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword"
class="text-danger"></span>
</div>
<button type="submit"
class="btn btn-primary">@_loc.Text("Register")</button>
</form>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
本地化DataAnnotations
如果你運行頁面並執行一些無效的輸入,你會發現驗證消息是英文的,因此我們需要本地化數據註釋消息,如Required、StringLength等。
打開Areas/Identity/Pages/Account/Register.cshtml.cs文件並在頂部添加LazZiya.ExpressLocalization.Messages的引用,它包含所有DataAnnotations錯誤消息的預定義結構,以便於使用:
@using LazZiya.ExpressLocalization.Messages;
然後修改輸入模型如下所示:
public class InputModel
{
[Required(ErrorMessage = DataAnnotationsErrorMessages.RequiredAttribute_ValidationError)]
[EmailAddress(ErrorMessage = DataAnnotationsErrorMessages.EmailAddressAttribute_Invalid)]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = DataAnnotationsErrorMessages.RequiredAttribute_ValidationError)]
[StringLength(100, ErrorMessage =
DataAnnotationsErrorMessages.StringLengthAttribute_ValidationErrorIncludingMinimum,
MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password",
ErrorMessage = DataAnnotationsErrorMessages.CompareAttribute_MustMatch)]
public string ConfirmPassword { get; set; }
}
編譯並允許項目,將看到本地化數據註釋的錯誤消息
客戶端驗證
服務器端驗證工作正常,但是我們仍然需要添加客戶端驗證,因此在提交表單之前,將在客戶端驗證輸入字段。
客戶端驗證的一個主要問題就是驗證數字、日期等本地化輸入。例如,如果你使用小數輸入,你講看到1.3的本地化數字驗證在英文中有效,但是對土耳其語無效,因爲它應爲1,3(逗號而不是句點)
在這裏,我們將使用LazZiya.TagHelpers附帶的另一個有用的tag helper。
打開Register.cshtml頁面並在默認驗證腳本partial下添加 tag helper。
@section Scripts {
<partial name="_ValidationScriptsPartial" />
<localization-validation-scripts></localization-validation-scripts>
}
這就是全部,現在將在使用本地化驗證消息提交表單之前驗證字段。
示例項目
你可以從Github下載包含超過19種語言包的示例項目
參考
在這裏閱讀有關使用nuget包的更多詳細信息:
- LazZiya.TagHelpers
- Manually installing client side localization validation scripts
- Manually creating language drop down navigation
- Even more can be found on my website http://ziyad.info
原文地址
https://www.codeproject.com/Articles/5061604/Developing-Multicultural-ASP-NET-Core-2-x-Project