ASP.NET Core で作成した Web アプリケーションにおいて、ユーザーが Web サイト上で言語を切り替えられるようにする方法です。
基本的には以下に書いてあります。
んで、サンプルコードが GitHub にあります。
若干説明不足な気もするので、メモとして書いておきます。
環境
- Visual Studio 2017
- ASP.NET Core 2.1
カルチャーの登録
Startup.cs
の ConfigureServices
メソッドで RequestLocalizationOptions
の設定を行います。
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en"),
new CultureInfo("ja"),
};
// State what the default culture for your application is. This will be used if no specific culture
// can be determined for a given request.
options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
// You must explicitly state which cultures your application supports.
// These are the cultures the app supports for formatting numbers, dates, etc.
options.SupportedCultures = supportedCultures;
// These are the cultures the app supports for UI strings, i.e. we have localized resources for.
options.SupportedUICultures = supportedCultures;
});
Configure
メソッドで設定を適用します。
var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
View
言語を切り替える UI を部分ビューとして Views/Shared/_SelectLanguagePartial.cshtml
に作成します。
以下はサンプルコードそのままです。
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
var cultureItems = LocOptions.Value.SupportedUICultures
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
<form id="selectLanguage" asp-controller="Home"
asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
method="post" class="form-horizontal" role="form">
<label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
onchange="this.form.submit();"
asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
</select>
</form>
</div>
ただ、このコードでは、コンボボックスの選択肢が常に日本語で表示されました。
英語に変更するには、以下の行
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
の DisplayName
を EnglishName
に変更します。
そして、この部分ビューを Views/Shared/_Layout.cshtml
の footer
で呼び出し、画面下部に常に表示されるようにします。
これもサンプルコードそのままです。
<div class="container body-content" style="margin-top:60px">
@RenderBody()
<hr>
<footer>
<div class="row">
<div class="col-md-6">
<p>© @System.DateTime.Now.Year - Localization</p>
</div>
<div class="col-md-6 text-right">
@await Html.PartialAsync("_SelectLanguagePartial")
</div>
</div>
</footer>
</div>
コンボボックスで言語を変更したときの処理を site.js
に書きます。
(function () {
$("#selectLanguage select").change(function () {
$(this).parent().submit();
});
}());
Controller
前述の View では、コンボボックスを切り替えた際に HomeController
の SetLanguage
というアクションメソッドがコールされるようになっているので、それを実装します。
これもサンプルコードそのままです。
[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return LocalRedirect(returnUrl);
}
以上で完了です。