ASP.NET Core Blazor 세계화 및 지역화
이 문서에서는 다양한 문화권 및 언어의 사용자를 위해 세계화되고 지역화된 콘텐츠를 렌더링하는 방법을 설명합니다.
세계화를 위해 Blazor는 숫자 및 날짜 서식을 제공합니다. 지역화를 위해 Blazor는 .NET 리소스 시스템을 사용하여 콘텐츠를 렌더링합니다.
제한된 ASP.NET Core 지역화 기능 모음이 지원됩니다.
✔️ IStringLocalizer 및 IStringLocalizer<T>가 Blazor 앱에서 지원됩니다.
❌IHtmlLocalizer, IViewLocalizer 및 데이터 주석 지역화는 ASP.NET Core MVC 기능으로, Blazor 앱에서 지원되지 않습니다.
이 문서에서는 다음을 기준으로 Blazor의 세계화 및 지역화 기능을 사용하는 방법을 설명합니다.
Accept-Language헤더 - 브라우저 설정에서 사용자의 언어 기본 설정에 따라 브라우저에 의해 설정됩니다.Accept-Language헤더의 값을 기준으로 하지 않는 앱에서 설정한 문화권. 이러한 설정은 모든 사용자에 대해 정적이거나 앱 논리에 따라 동적일 수 있습니다. 설정이 사용자의 기본 설정을 기준으로 하는 경우 일반적으로 나중에 방문할 때 다시 로드할 수 있게 저장됩니다.
추가적인 일반 정보에 대해서는 ASP.NET Core의 전역화 및 지역화를 참조하세요.
참고
‘언어’와 ‘문화권’이라는 용어는 세계화와 지역화 개념을 처리할 때 서로 바꿔서 사용되는 경우가 많습니다.
이 문서에서 언어는 브라우저 설정에서 사용자가 선택한 항목을 나타냅니다. 사용자의 언어 선택은 브라우저 요청의 Accept-Language 헤더로 제출됩니다. 브라우저 설정은 일반적으로 UI에서 "언어"라는 단어를 사용합니다.
문화권은 .NET 및 Blazor API의 멤버와 관련이 있습니다. 예를 들어, 사용자의 요청에는 사용자의 관점에서 언어를 지정하는 Accept-Language 헤더가 포함될 수 있지만, 앱은 궁극적으로 사용자가 요청한 언어의 CurrentCulture("culture") 속성을 설정합니다. API는 일반적으로 멤버 이름에 "culture"라는 단어를 사용합니다.
전역화
@bind 특성 지시문은 형식을 적용하고 앱에서 지원하는 사용자의 첫 번째 기본 설정 언어를 기준으로 표시 값을 구문 분석합니다. @bind는 @bind:culture 매개 변수를 지원하여 값을 구문 분석하고 서식을 지정하기 위한 System.Globalization.CultureInfo을 제공합니다.
현재 문화권은 System.Globalization.CultureInfo.CurrentCulture 속성에서 액세스할 수 있습니다.
CultureInfo.InvariantCulture는 다음 필드 형식(<input type="{TYPE}" />)에 사용됩니다. 여기서 {TYPE} 자리 표시자는 형식입니다.
datenumber
이전 필드 형식:
- 적절한 브라우저 기반 서식 지정 규칙을 사용하여 표시됩니다.
- 자유 형식 텍스트를 포함할 수 없습니다.
- 브라우저의 구현에 따라 사용자 상호 작용 특성을 제공합니다.
date 및 number 필드 형식을 사용하는 경우 Blazor는 현재 문화권에서 값을 렌더링하는 기본 제공 지원을 제공하므로 @bind:culture를 사용하여 문화권을 지정하는 것은 권장되지 않습니다.
다음 필드 형식은 특정 형식 지정 요구 사항이 있으며, 모든 주요 브라우저에서 지원되는 것은 아니므로 현재 Blazor에서 지원되지 않습니다.
datetime-localmonthweek
이전 형식의 현재 브라우저 지원에 대한 자세한 내용은 Can I use를 참조하세요.
고정 세계화
앱에 지역화가 필요하지 않은 경우 일반적으로 미국 영어(en-US)를 기준으로 하는 고정 문화권을 지원하도록 앱을 구성합니다. 앱의 프로젝트 파일(.csproj)에서 InvariantGlobalization 속성을 true로 설정합니다.
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
또는 다음 방식으로 고정 세계화를 구성합니다.
runtimeconfig.json의 경우{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }환경 변수 사용:
- 키:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT - 값:
true또는1
- 키:
자세한 내용은 세계화를 위한 런타임 구성 옵션(.NET 설명서)을 참조하세요.
데모 구성 요소
다음 CultureExample1 구성 요소는 이 문서에서 다루는 Blazor 세계화 및 지역화 개념을 보여 주는 데 사용할 수 있습니다.
Pages/CultureExample1.razor:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
앞의 예제(.ToString("N2"))에 나오는 숫자 문자열 형식(N2)은 표준 .NET 숫자 형식 지정자입니다. N2 형식은 모든 숫자 형식에 대해 지원되며, 그룹 구분 기호를 포함하고, 소수점 이하 두 자리까지 렌더링됩니다.
필요에 따라 CultureExample1 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.
Accept-Language 헤더에서 문화권을 동적으로 설정
Accept-Language 헤더는 브라우저에서 설정되며 브라우저 설정의 사용자 언어 기본 설정에 의해 제어됩니다. 브라우저 설정에서 사용자는 기본 설정 순서대로 하나 이상의 기본 설정 언어를 지정합니다. 기본 설정 순서는 브라우저에서 헤더의 각 언어에 대한 품질 값(q, 0-1)을 설정하는 데 사용됩니다. 다음 예제에서는 미국 영어 또는 영어에 대한 기본 설정을 사용하여 미국 영어, 영어 및 칠레 스페인어를 지정합니다.
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
앱의 문화권은 앱의 지원되는 문화권과 일치하는 첫 번째로 요청된 언어를 일치시켜 설정됩니다.
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
참고
앱 사양에서 지원되는 문화권을 명시적 목록으로 제한해야 하는 경우 이 문서의 사용자 기본 설정 섹션을 통해 문화권을 동적으로 설정을 참조하세요.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Program.cs의 경우
builder.Services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Program.cs에서 앱의 지원되는 문화권을 지정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Program.cs의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다.
참고
일부 브라우저에서는 요청 및 브라우저의 자체 UI 설정 모두에 대해 강제로 기본 언어 설정을 사용하도록 합니다. 이렇게 하면 모든 설정 UI 화면이 읽을 수 없는 언어로 표시될 수 있으므로 언어를 이해할 수 있는 언어로 변경하는 것이 어려울 수 있습니다. Opera와 같은 브라우저에서는 웹 페이지 요청에 대한 기본 언어를 설정할 수 있지만 브라우저의 설정 UI를 사용 중인 언어로 그대로 둘 수 있으므로 테스트에 적합합니다.
문화권이 미국 영어(en-US)인 경우 렌더링된 구성 요소는 월/일 날짜 서식(6/7), 12시간 형식(AM/PM), 쉼표를 숫자 구분 기호로, 점을 소숫점으로 사용합니다(1,999.69).
- 날짜: 6/7/2021 6:45:22 AM
- 숫자: 1,999.69
문화권이 칠레 스페인어(es-CL)인 경우 렌더링된 구성 요소는 일/월 날짜 서식(7/6), 24시간 형식, 마침표를 숫자 구분 기호로, 쉼표를 소숫점으로 사용합니다(1.999,69).
- 날짜: 7/6/2021 6:49:38
- 숫자: 1.999,69
정적으로 문화권 설정
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor가 applicationCultureBlazor 시작 옵션으로 시작될 때 JavaScript에서 앱의 문화권을 설정할 수 있습니다. 다음 예제에서는 미국 영어(en-US) 문화권을 사용하여 앱을 시작하도록 구성합니다.
wwwroot/index.html에서autostart="false"을 Blazor의<script>태그에 추가하여 Blazor 자동 시작을 방지합니다.<script src="_framework/blazor.webassembly.js" autostart="false"></script>Blazor의
<script>태그 뒤, 닫는</body>태그 앞에 다음<script>블록을 추가합니다.<script> Blazor.start({ applicationCulture: 'en-US' }); </script>
applicationCulture의 값은 BCP-47 언어 태그 형식을 준수해야 합니다. Blazor 시작에 대한 자세한 내용은 ASP.NET Core Blazor 시작을 참조하세요.
문화권 Blazor의 시작 옵션을 설정하는 또 다른 방법은 C# 코드에서 문화권을 설정하는 것입니다. Program.cs에서 CultureInfo.DefaultThreadCurrentCulture 및 CultureInfo.DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
System.Globalization 네임스페이스를 Program.cs에 추가합니다.
using System.Globalization;
WebAssemblyHostBuilder을 빌드하고 실행하는 줄 앞에 문화권 설정을 추가합니다(await builder.Build().RunAsync();).
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
중요
IStringLocalizer 및 IStringLocalizer<T>를 사용하려면 항상 DefaultThreadCurrentCulture 및 DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Program.cs의 경우
builder.Services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Program.cs에서 정적 문화권을 지정합니다. 다음 예제에서는 미국 영어를 구성합니다.
app.UseRequestLocalization("en-US");
UseRequestLocalization의 문화권 값은 BCP-47 언어 태그 형식을 준수해야 합니다.
Program.cs의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다. 요청된 언어가 칠레 스페인어인 경우 앱의 문화권은 미국 영어(en-US)로 유지됩니다.
사용자 기본 설정에 따라 문화권을 동적으로 설정
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 브라우저 로컬 스토리지를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
프로젝트 파일에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor WebAssembly 앱의 앱 문화권은 Blazor 프레임워크의 API를 사용하여 설정됩니다. 사용자의 문화권 선택은 브라우저 로컬 스토리지에 유지할 수 있습니다.
Blazor의 <script> 태그 뒤, 닫는 </body> 태그 앞에 있는 wwwroot/index.html 파일에서 브라우저 로컬 스토리지를 사용하여 사용자의 문화권 선택을 가져오고 설정하기 위한 JS 함수를 제공합니다.
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
참고
앞의 예제에서는 전역 메서드를 사용하여 클라이언트를 오염시킵니다. 프로덕션 앱에서의 더 나은 접근 방식은 JavaScript 모듈에서의 JavaScript 격리를 참조하세요.
예제:
export function getBlazorCulture() {
return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
window.localStorage['BlazorCulture'] = value;
};
위의 함수를 사용하는 경우 이 섹션의 JS interop 호출을 blazorCulture.get에서 getBlazorCulture(으)로, 또는 blazorCulture.set에서 setBlazorCulture(으)로 변경합니다.
System.Globalization 및 Microsoft.JSInterop의 네임스페이스를 Program.cs의 맨 위에 추가합니다.
using System.Globalization;
using Microsoft.JSInterop;
Program.cs에서 다음 줄을 제거합니다.
- await builder.Build().RunAsync();
앞의 줄을 다음 코드로 바꿉니다. 이 코드는 AddLocalization을(를) 사용하여 Blazor의 지역화 서비스를 앱의 서비스 컬렉션에 추가하고 JSinterop을 사용하여 JS으(로) 호출하고 로컬 스토리지에서 사용자의 문화권 선택을 검색합니다. 로컬 스토리지에 사용자에 대한 문화권이 없는 경우 코드는 기본값인 미국 영어(en-US)를 설정합니다.
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
중요
IStringLocalizer 및 IStringLocalizer<T>를 사용하려면 항상 DefaultThreadCurrentCulture 및 DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
다음 CultureSelector 구성 요소는 다음 작업을 수행하는 방법을 보여줍니다.
- JS interop을 통해 사용자의 문화권 선택을 브라우저 로컬 스토리지로 설정합니다.
- 요청한(
forceLoad: true) 구성 요소를 다시 로드합니다. 이 구성 요소는 업데이트된 문화권을 사용합니다.
CultureSelector 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Nav.NavigateTo(Nav.Uri, forceLoad: true);
}
}
}
}
참고
IJSInProcessRuntime에 대한 자세한 내용은 ASP.NET Core의 .NET 메서드에서 JavaScript 함수 호출Blazor을 참조하세요.
Shared/MainLayout.razor에서 <main> 요소의 닫는 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 지역화 cookie를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Program.cs의 경우
builder.Services.AddLocalization();
RequestLocalizationOptions을 통해 앱의 기본 문화권 및 지원되는 문화권을 설정합니다.
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Program.cs에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
다음 예제에서는 지역화 미들웨어에서 읽을 수 있는 cookie의 현재 문화권을 설정하는 방법을 보여 줍니다.
Pages/_Host.cshtml 파일을 수정하려면 다음 네임스페이스가 필요합니다.
Pages/_Host.cshtml:
@page "/"
@namespace {NAMESPACE}.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
Layout = "_Layout";
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
<component type="typeof(App)" render-mode="ServerPrerendered" />
앞의 예제에서 {NAMESPACE} 자리 표시자는 앱의 어셈블리 이름입니다.
Program.cs의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 컨트롤러 작업을 처리하도록 구성되지 않은 경우 다음과 같습니다.
Program.cs의 서비스 컬렉션에서 AddControllers를 호출하여 MVC 서비스를 추가합니다.builder.Services.AddControllers();IEndpointRouteBuilder에서 MapControllers를 호출하여
Program.cs에 컨트롤러 엔드포인트 라우팅을 추가합니다.app.MapControllers();다음 예제에서는 줄이 추가된 후 UseEndpoints에 대한 호출을 보여 줍니다.
app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host");
사용자가 문화권을 선택하기 위한 UI를 제공하려면 지역화 cookie에서 리디렉션 기반 접근 방식을 사용합니다. 앱은 컨트롤러에 대한 리디렉션을 통해 사용자가 선택한 문화권을 유지합니다. 컨트롤러는 사용자가 선택한 문화권을 cookie로 설정하고 사용자를 원래 URI로 다시 리디렉션합니다. 이 프로세스는 사용자가 보안 리소스에 액세스하려고 할 때 웹앱에서 발생하는 작업과 비슷합니다. 즉, 사용자는 로그인 페이지로 리디렉션되고 다시 원래 리소스로 리디렉션됩니다.
Controllers/CultureController.cs:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
경고
LocalRedirect 작업 결과를 사용하여 오픈 리디렉션 공격을 방지합니다. 자세한 내용은 ASP.NET Core에서 오픈 리디렉션 공격 방지를 참조하세요.
다음 CultureSelector 구성 요소는 새 문화권으로 CultureController의 Set 메서드를 호출하는 방법을 보여줍니다. 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Nav.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Nav.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor에서 <div class="main"> 요소의 닫는 </div> 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 이전 예제의 작동 방식을 알아봅니다.
지역화
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우 앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program.cs에서 System.Globalization의 네임스페이스를 파일 맨 위에 추가합니다.
using System.Globalization;
Program.cs에서 AddLocalization를 사용하여 앱의 서비스 컬렉션에 Blazor의 지역화 서비스를 추가합니다.
builder.Services.AddLocalization();
지역화 미들웨어를 사용하여 앱의 문화권을 설정합니다.
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우:
- AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Program.cs에서 앱의 기본 문화권과 지원되는 문화권을 설정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
Program.cs의 경우
builder.Services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Program.cs에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 사용자의 문화권 설정 저장에 따라 리소스를 지역화해야 하는 경우 지역화 문화권 cookie를 사용합니다. cookie를 사용하면 WebSocket 연결이 문화권을 올바르게 전파할 수 있게 됩니다. 지역화 체계가 URL 경로 또는 쿼리 문자열을 기준으로 하는 경우 스키마는 WebSocket을 사용하지 못할 수 있으므로 문화권이 유지되지 않습니다. 따라서 지역화 문화권 cookie를 사용하는 것이 좋습니다. 사용자의 문화권 선택을 유지하는 Pages/_Layout.cshtml 파일에 대한 예제 Razor 식을 보려면 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션을 참조하세요.
이 섹션의 지역화된 리소스 예제는 이 문서의 이전 예제에서 작동합니다. 여기서 앱의 지원되는 문화권은 영어(en)를 기본 로케일로 사용하고 스페인어(es)를 사용자가 선택할 수 있거나 브라우저에서 지정되는 대체 로케일로 사용합니다.
각 로케일에 대한 리소스를 만듭니다. 다음 예제에서는 기본 Greeting 문자열에 대한 리소스가 만들어집니다.
- 영어:
Hello, World! - 스페인어(
es):¡Hola, Mundo!
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 Hello, World!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>Hello, World!</value>
</data>
</root>
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.es.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 ¡Hola, Mundo!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.es.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>¡Hola, Mundo!</value>
</data>
</root>
다음 구성 요소는 IStringLocalizer<T>와 함께 지역화된 Greeting 문자열을 사용하는 방법을 보여 줍니다. 다음 예제의 Razor 태그 @Loc["Greeting"]은 이전 리소스 파일에 설정된 Greeting 값으로 키가 지정된 문자열을 지역화합니다.
Microsoft.Extensions.Localization에 대한 네임스페이스를 앱의 _Imports.razor 파일에 추가합니다.
@using Microsoft.Extensions.Localization
Pages/CultureExample2.razor:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
필요에 따라 CultureExample2 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.
문화권 공급자 참조 원본
Blazor 프레임워크가 지역화를 처리하는 방법을 자세히 이해하려면 ASP.NET Core 참조 원본의 WebAssemblyCultureProvider 클래스를 참조하세요.
참고
.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.
추가 자료
세계화를 위해 Blazor는 숫자 및 날짜 서식을 제공합니다. 지역화를 위해 Blazor는 .NET 리소스 시스템을 사용하여 콘텐츠를 렌더링합니다.
제한된 ASP.NET Core 지역화 기능 모음이 지원됩니다.
✔️ IStringLocalizer 및 IStringLocalizer<T>가 Blazor 앱에서 지원됩니다.
❌IHtmlLocalizer, IViewLocalizer 및 데이터 주석 지역화는 ASP.NET Core MVC 기능으로, Blazor 앱에서 지원되지 않습니다.
이 문서에서는 다음을 기준으로 Blazor의 세계화 및 지역화 기능을 사용하는 방법을 설명합니다.
Accept-Language헤더 - 브라우저 설정에서 사용자의 언어 기본 설정에 따라 브라우저에 의해 설정됩니다.Accept-Language헤더의 값을 기준으로 하지 않는 앱에서 설정한 문화권. 이러한 설정은 모든 사용자에 대해 정적이거나 앱 논리에 따라 동적일 수 있습니다. 설정이 사용자의 기본 설정을 기준으로 하는 경우 일반적으로 나중에 방문할 때 다시 로드할 수 있게 저장됩니다.
추가적인 일반 정보에 대해서는 ASP.NET Core의 전역화 및 지역화를 참조하세요.
참고
‘언어’와 ‘문화권’이라는 용어는 세계화와 지역화 개념을 처리할 때 서로 바꿔서 사용되는 경우가 많습니다.
이 문서에서 언어는 브라우저 설정에서 사용자가 선택한 항목을 나타냅니다. 사용자의 언어 선택은 브라우저 요청의 Accept-Language 헤더로 제출됩니다. 브라우저 설정은 일반적으로 UI에서 "언어"라는 단어를 사용합니다.
문화권은 .NET 및 Blazor API의 멤버와 관련이 있습니다. 예를 들어, 사용자의 요청에는 사용자의 관점에서 언어를 지정하는 Accept-Language 헤더가 포함될 수 있지만, 앱은 궁극적으로 사용자가 요청한 언어의 CurrentCulture("culture") 속성을 설정합니다. API는 일반적으로 멤버 이름에 "culture"라는 단어를 사용합니다.
전역화
@bind 특성 지시문은 형식을 적용하고 앱에서 지원하는 사용자의 첫 번째 기본 설정 언어를 기준으로 표시 값을 구문 분석합니다. @bind는 @bind:culture 매개 변수를 지원하여 값을 구문 분석하고 서식을 지정하기 위한 System.Globalization.CultureInfo을 제공합니다.
현재 문화권은 System.Globalization.CultureInfo.CurrentCulture 속성에서 액세스할 수 있습니다.
CultureInfo.InvariantCulture는 다음 필드 형식(<input type="{TYPE}" />)에 사용됩니다. 여기서 {TYPE} 자리 표시자는 형식입니다.
datenumber
이전 필드 형식:
- 적절한 브라우저 기반 서식 지정 규칙을 사용하여 표시됩니다.
- 자유 형식 텍스트를 포함할 수 없습니다.
- 브라우저의 구현에 따라 사용자 상호 작용 특성을 제공합니다.
date 및 number 필드 형식을 사용하는 경우 Blazor는 현재 문화권에서 값을 렌더링하는 기본 제공 지원을 제공하므로 @bind:culture를 사용하여 문화권을 지정하는 것은 권장되지 않습니다.
다음 필드 형식은 특정 형식 지정 요구 사항이 있으며, 모든 주요 브라우저에서 지원되는 것은 아니므로 현재 Blazor에서 지원되지 않습니다.
datetime-localmonthweek
이전 형식의 현재 브라우저 지원에 대한 자세한 내용은 Can I use를 참조하세요.
고정 세계화
앱에 지역화가 필요하지 않은 경우 일반적으로 미국 영어(en-US)를 기준으로 하는 고정 문화권을 지원하도록 앱을 구성합니다. 앱의 프로젝트 파일(.csproj)에서 InvariantGlobalization 속성을 true로 설정합니다.
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
또는 다음 방식으로 고정 세계화를 구성합니다.
runtimeconfig.json의 경우{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }환경 변수 사용:
- 키:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT - 값:
true또는1
- 키:
자세한 내용은 세계화를 위한 런타임 구성 옵션(.NET 설명서)을 참조하세요.
데모 구성 요소
다음 CultureExample1 구성 요소는 이 문서에서 다루는 Blazor 세계화 및 지역화 개념을 보여 주는 데 사용할 수 있습니다.
Pages/CultureExample1.razor:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
앞의 예제(.ToString("N2"))에 나오는 숫자 문자열 형식(N2)은 표준 .NET 숫자 형식 지정자입니다. N2 형식은 모든 숫자 형식에 대해 지원되며, 그룹 구분 기호를 포함하고, 소수점 이하 두 자리까지 렌더링됩니다.
필요에 따라 CultureExample1 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.
Accept-Language 헤더에서 문화권을 동적으로 설정
Accept-Language 헤더는 브라우저에서 설정되며 브라우저 설정의 사용자 언어 기본 설정에 의해 제어됩니다. 브라우저 설정에서 사용자는 기본 설정 순서대로 하나 이상의 기본 설정 언어를 지정합니다. 기본 설정 순서는 브라우저에서 헤더의 각 언어에 대한 품질 값(q, 0-1)을 설정하는 데 사용됩니다. 다음 예제에서는 미국 영어 또는 영어에 대한 기본 설정을 사용하여 미국 영어, 영어 및 칠레 스페인어를 지정합니다.
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
앱의 문화권은 앱의 지원되는 문화권과 일치하는 첫 번째로 요청된 언어를 일치시켜 설정됩니다.
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
참고
앱 사양에서 지원되는 문화권을 명시적 목록으로 제한해야 하는 경우 이 문서의 사용자 기본 설정 섹션을 통해 문화권을 동적으로 설정을 참조하세요.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Startup.Configure(Startup.cs)에서 앱의 지원되는 문화권을 지정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다.
참고
일부 브라우저에서는 요청 및 브라우저의 자체 UI 설정 모두에 대해 강제로 기본 언어 설정을 사용하도록 합니다. 이렇게 하면 모든 설정 UI 화면이 읽을 수 없는 언어로 표시될 수 있으므로 언어를 이해할 수 있는 언어로 변경하는 것이 어려울 수 있습니다. Opera와 같은 브라우저에서는 웹 페이지 요청에 대한 기본 언어를 설정할 수 있지만 브라우저의 설정 UI를 사용 중인 언어로 그대로 둘 수 있으므로 테스트에 적합합니다.
문화권이 미국 영어(en-US)인 경우 렌더링된 구성 요소는 월/일 날짜 서식(6/7), 12시간 형식(AM/PM), 쉼표를 숫자 구분 기호로, 점을 소숫점으로 사용합니다(1,999.69).
- 날짜: 6/7/2021 6:45:22 AM
- 숫자: 1,999.69
문화권이 칠레 스페인어(es-CL)인 경우 렌더링된 구성 요소는 일/월 날짜 서식(7/6), 24시간 형식, 마침표를 숫자 구분 기호로, 쉼표를 소숫점으로 사용합니다(1.999,69).
- 날짜: 7/6/2021 6:49:38
- 숫자: 1.999,69
정적으로 문화권 설정
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor가 applicationCultureBlazor 시작 옵션으로 시작될 때 JavaScript에서 앱의 문화권을 설정할 수 있습니다. 다음 예제에서는 미국 영어(en-US) 문화권을 사용하여 앱을 시작하도록 구성합니다.
wwwroot/index.html에서autostart="false"을 Blazor의<script>태그에 추가하여 Blazor 자동 시작을 방지합니다.<script src="_framework/blazor.webassembly.js" autostart="false"></script>Blazor의
<script>태그 뒤, 닫는</body>태그 앞에 다음<script>블록을 추가합니다.<script> Blazor.start({ applicationCulture: 'en-US' }); </script>
applicationCulture의 값은 BCP-47 언어 태그 형식을 준수해야 합니다. Blazor 시작에 대한 자세한 내용은 ASP.NET Core Blazor 시작을 참조하세요.
문화권 Blazor의 시작 옵션을 설정하는 또 다른 방법은 C# 코드에서 문화권을 설정하는 것입니다. Program.cs에서 CultureInfo.DefaultThreadCurrentCulture 및 CultureInfo.DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
System.Globalization 네임스페이스를 Program.cs에 추가합니다.
using System.Globalization;
WebAssemblyHostBuilder을 빌드하고 실행하는 줄 앞에 문화권 설정을 추가합니다(await builder.Build().RunAsync();).
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
중요
IStringLocalizer 및 IStringLocalizer<T>를 사용하려면 항상 DefaultThreadCurrentCulture 및 DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Startup.Configure(Startup.cs)에서 정적 문화권을 지정합니다. 다음 예제에서는 미국 영어를 구성합니다.
app.UseRequestLocalization("en-US");
UseRequestLocalization의 문화권 값은 BCP-47 언어 태그 형식을 준수해야 합니다.
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다. 요청된 언어가 칠레 스페인어인 경우 앱의 문화권은 미국 영어(en-US)로 유지됩니다.
사용자 기본 설정에 따라 문화권을 동적으로 설정
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 브라우저 로컬 스토리지를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
프로젝트 파일에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor WebAssembly 앱의 앱 문화권은 Blazor 프레임워크의 API를 사용하여 설정됩니다. 사용자의 문화권 선택은 브라우저 로컬 스토리지에 유지할 수 있습니다.
Blazor의 <script> 태그 뒤, 닫는 </body> 태그 앞에 있는 wwwroot/index.html 파일에서 브라우저 로컬 스토리지를 사용하여 사용자의 문화권 선택을 가져오고 설정하기 위한 JS 함수를 제공합니다.
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
참고
앞의 예제에서는 전역 메서드를 사용하여 클라이언트를 오염시킵니다. 프로덕션 앱에서의 더 나은 접근 방식은 JavaScript 모듈에서의 JavaScript 격리를 참조하세요.
예제:
export function getBlazorCulture() {
return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
window.localStorage['BlazorCulture'] = value;
};
위의 함수를 사용하는 경우 이 섹션의 JS interop 호출을 blazorCulture.get에서 getBlazorCulture(으)로, 또는 blazorCulture.set에서 setBlazorCulture(으)로 변경합니다.
System.Globalization 및 Microsoft.JSInterop의 네임스페이스를 Program.cs의 맨 위에 추가합니다.
using System.Globalization;
using Microsoft.JSInterop;
Program.cs에서 다음 줄을 제거합니다.
- await builder.Build().RunAsync();
앞의 줄을 다음 코드로 바꿉니다. 이 코드는 AddLocalization을(를) 사용하여 Blazor의 지역화 서비스를 앱의 서비스 컬렉션에 추가하고 JSinterop을 사용하여 JS으(로) 호출하고 로컬 스토리지에서 사용자의 문화권 선택을 검색합니다. 로컬 스토리지에 사용자에 대한 문화권이 없는 경우 코드는 기본값인 미국 영어(en-US)를 설정합니다.
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
중요
IStringLocalizer 및 IStringLocalizer<T>를 사용하려면 항상 DefaultThreadCurrentCulture 및 DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
다음 CultureSelector 구성 요소는 JS interop을 통해 사용자의 문화권 선택을 브라우저 로컬 스토리지로 설정하는 방법을 보여 줍니다. 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Nav.NavigateTo(Nav.Uri, forceLoad: true);
}
}
}
}
참고
IJSInProcessRuntime에 대한 자세한 내용은 ASP.NET Core의 .NET 메서드에서 JavaScript 함수 호출Blazor을 참조하세요.
Shared/MainLayout.razor에서 <div class="main"> 요소의 닫는 </div> 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 지역화 cookie를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
RequestLocalizationOptions을 통해 앱의 기본 문화권 및 지원되는 문화권을 설정합니다.
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Startup.Configure에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
다음 예제에서는 지역화 미들웨어에서 읽을 수 있는 cookie의 현재 문화권을 설정하는 방법을 보여 줍니다.
다음 네임스페이스를 Pages/_Host.cshtml 파일 맨 위에 추가합니다.
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Pages/_Host.cshtml의 여는 <body> 태그 바로 다음에 다음 Razor 식을 추가합니다.
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 컨트롤러 작업을 처리하도록 구성되지 않은 경우 다음과 같습니다.
Startup.ConfigureServices의 서비스 컬렉션에서 AddControllers를 호출하여 MVC 서비스를 추가합니다.services.AddControllers();IEndpointRouteBuilder에서 MapControllers를 호출하여
Startup.Configure에 컨트롤러 엔드포인트 라우팅을 추가합니다.endpoints.MapControllers();다음 예제에서는 줄이 추가된 후 UseEndpoints에 대한 호출을 보여 줍니다.
app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
사용자가 문화권을 선택하기 위한 UI를 제공하려면 지역화 cookie에서 리디렉션 기반 접근 방식을 사용합니다. 앱은 컨트롤러에 대한 리디렉션을 통해 사용자가 선택한 문화권을 유지합니다. 컨트롤러는 사용자가 선택한 문화권을 cookie로 설정하고 사용자를 원래 URI로 다시 리디렉션합니다. 이 프로세스는 사용자가 보안 리소스에 액세스하려고 할 때 웹앱에서 발생하는 작업과 비슷합니다. 즉, 사용자는 로그인 페이지로 리디렉션되고 다시 원래 리소스로 리디렉션됩니다.
Controllers/CultureController.cs:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
경고
LocalRedirect 작업 결과를 사용하여 오픈 리디렉션 공격을 방지합니다. 자세한 내용은 ASP.NET Core에서 오픈 리디렉션 공격 방지를 참조하세요.
다음 CultureSelector 구성 요소는 사용자가 문화권을 선택할 때 초기 리디렉션을 수행하는 방법의 예를 보여 줍니다. 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Nav.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Nav.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor에서 <div class="main"> 요소의 닫는 </div> 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 이전 예제의 작동 방식을 알아봅니다.
지역화
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우 앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
앱의 프로젝트 파일(.csproj)에서 BlazorWebAssemblyLoadAllGlobalizationData 속성을 true로 설정합니다.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program.cs에서 System.Globalization의 네임스페이스를 파일 맨 위에 추가합니다.
using System.Globalization;
Program.cs에서 AddLocalization를 사용하여 앱의 서비스 컬렉션에 Blazor의 지역화 서비스를 추가합니다.
builder.Services.AddLocalization();
지역화 미들웨어를 사용하여 앱의 문화권을 설정합니다.
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우:
- AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.Configure(Startup.cs)에서 앱의 기본 문화권 및 지원되는 문화권을 설정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Startup.Configure에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 사용자의 문화권 설정 저장에 따라 리소스를 지역화해야 하는 경우 지역화 문화권 cookie를 사용합니다. cookie를 사용하면 WebSocket 연결이 문화권을 올바르게 전파할 수 있게 됩니다. 지역화 체계가 URL 경로 또는 쿼리 문자열을 기준으로 하는 경우 스키마는 WebSocket을 사용하지 못할 수 있으므로 문화권이 유지되지 않습니다. 따라서 지역화 문화권 cookie를 사용하는 것이 좋습니다. 사용자의 문화권 선택을 유지하는 Pages/_Host.cshtml 파일에 대한 예제 Razor 식을 보려면 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션을 참조하세요.
이 섹션의 지역화된 리소스 예제는 이 문서의 이전 예제에서 작동합니다. 여기서 앱의 지원되는 문화권은 영어(en)를 기본 로케일로 사용하고 스페인어(es)를 사용자가 선택할 수 있거나 브라우저에서 지정되는 대체 로케일로 사용합니다.
각 로케일에 대한 리소스를 만듭니다. 다음 예제에서는 기본 Greeting 문자열에 대한 리소스가 만들어집니다.
- 영어:
Hello, World! - 스페인어(
es):¡Hola, Mundo!
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 Hello, World!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>Hello, World!</value>
</data>
</root>
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.es.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 ¡Hola, Mundo!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.es.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>¡Hola, Mundo!</value>
</data>
</root>
다음 구성 요소는 IStringLocalizer<T>와 함께 지역화된 Greeting 문자열을 사용하는 방법을 보여 줍니다. 다음 예제의 Razor 태그 @Loc["Greeting"]은 이전 리소스 파일에 설정된 Greeting 값으로 키가 지정된 문자열을 지역화합니다.
Microsoft.Extensions.Localization에 대한 네임스페이스를 앱의 _Imports.razor 파일에 추가합니다.
@using Microsoft.Extensions.Localization
Pages/CultureExample2.razor:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
필요에 따라 CultureExample2 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.
문화권 공급자 참조 원본
Blazor 프레임워크가 지역화를 처리하는 방법을 자세히 이해하려면 ASP.NET Core 참조 원본의 WebAssemblyCultureProvider 클래스를 참조하세요.
참고
.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.
추가 자료
세계화를 위해 Blazor는 숫자 및 날짜 서식을 제공합니다. 지역화를 위해 Blazor는 .NET 리소스 시스템을 사용하여 콘텐츠를 렌더링합니다.
제한된 ASP.NET Core 지역화 기능 모음이 지원됩니다.
✔️ IStringLocalizer 및 IStringLocalizer<T>가 Blazor 앱에서 지원됩니다.
❌IHtmlLocalizer, IViewLocalizer 및 데이터 주석 지역화는 ASP.NET Core MVC 기능으로, Blazor 앱에서 지원되지 않습니다.
이 문서에서는 다음을 기준으로 Blazor의 세계화 및 지역화 기능을 사용하는 방법을 설명합니다.
Accept-Language헤더 - 브라우저 설정에서 사용자의 언어 기본 설정에 따라 브라우저에 의해 설정됩니다.Accept-Language헤더의 값을 기준으로 하지 않는 앱에서 설정한 문화권. 이러한 설정은 모든 사용자에 대해 정적이거나 앱 논리에 따라 동적일 수 있습니다. 설정이 사용자의 기본 설정을 기준으로 하는 경우 일반적으로 나중에 방문할 때 다시 로드할 수 있게 저장됩니다.
추가적인 일반 정보에 대해서는 ASP.NET Core의 전역화 및 지역화를 참조하세요.
참고
‘언어’와 ‘문화권’이라는 용어는 세계화와 지역화 개념을 처리할 때 서로 바꿔서 사용되는 경우가 많습니다.
이 문서에서 언어는 브라우저 설정에서 사용자가 선택한 항목을 나타냅니다. 사용자의 언어 선택은 브라우저 요청의 Accept-Language 헤더로 제출됩니다. 브라우저 설정은 일반적으로 UI에서 "언어"라는 단어를 사용합니다.
문화권은 .NET 및 Blazor API의 멤버와 관련이 있습니다. 예를 들어, 사용자의 요청에는 사용자의 관점에서 언어를 지정하는 Accept-Language 헤더가 포함될 수 있지만, 앱은 궁극적으로 사용자가 요청한 언어의 CurrentCulture("culture") 속성을 설정합니다. API는 일반적으로 멤버 이름에 "culture"라는 단어를 사용합니다.
전역화
@bind 특성 지시문은 형식을 적용하고 앱에서 지원하는 사용자의 첫 번째 기본 설정 언어를 기준으로 표시 값을 구문 분석합니다. @bind는 @bind:culture 매개 변수를 지원하여 값을 구문 분석하고 서식을 지정하기 위한 System.Globalization.CultureInfo을 제공합니다.
현재 문화권은 System.Globalization.CultureInfo.CurrentCulture 속성에서 액세스할 수 있습니다.
CultureInfo.InvariantCulture는 다음 필드 형식(<input type="{TYPE}" />)에 사용됩니다. 여기서 {TYPE} 자리 표시자는 형식입니다.
datenumber
이전 필드 형식:
- 적절한 브라우저 기반 서식 지정 규칙을 사용하여 표시됩니다.
- 자유 형식 텍스트를 포함할 수 없습니다.
- 브라우저의 구현에 따라 사용자 상호 작용 특성을 제공합니다.
date 및 number 필드 형식을 사용하는 경우 Blazor는 현재 문화권에서 값을 렌더링하는 기본 제공 지원을 제공하므로 @bind:culture를 사용하여 문화권을 지정하는 것은 권장되지 않습니다.
다음 필드 형식은 특정 형식 지정 요구 사항이 있으며, 모든 주요 브라우저에서 지원되는 것은 아니므로 현재 Blazor에서 지원되지 않습니다.
datetime-localmonthweek
이전 형식의 현재 브라우저 지원에 대한 자세한 내용은 Can I use를 참조하세요.
고정 세계화
앱에 지역화가 필요하지 않은 경우 일반적으로 미국 영어(en-US)를 기준으로 하는 고정 문화권을 지원하도록 앱을 구성합니다. 앱의 프로젝트 파일(.csproj)에서 InvariantGlobalization 속성을 true로 설정합니다.
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
또는 다음 방식으로 고정 세계화를 구성합니다.
runtimeconfig.json의 경우{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }환경 변수 사용:
- 키:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT - 값:
true또는1
- 키:
자세한 내용은 세계화를 위한 런타임 구성 옵션(.NET 설명서)을 참조하세요.
데모 구성 요소
다음 CultureExample1 구성 요소는 이 문서에서 다루는 Blazor 세계화 및 지역화 개념을 보여 주는 데 사용할 수 있습니다.
Pages/CultureExample1.razor:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
앞의 예제(.ToString("N2"))에 나오는 숫자 문자열 형식(N2)은 표준 .NET 숫자 형식 지정자입니다. N2 형식은 모든 숫자 형식에 대해 지원되며, 그룹 구분 기호를 포함하고, 소수점 이하 두 자리까지 렌더링됩니다.
필요에 따라 CultureExample1 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.
Accept-Language 헤더에서 문화권을 동적으로 설정
Accept-Language 헤더는 브라우저에서 설정되며 브라우저 설정의 사용자 언어 기본 설정에 의해 제어됩니다. 브라우저 설정에서 사용자는 기본 설정 순서대로 하나 이상의 기본 설정 언어를 지정합니다. 기본 설정 순서는 브라우저에서 헤더의 각 언어에 대한 품질 값(q, 0-1)을 설정하는 데 사용됩니다. 다음 예제에서는 미국 영어 또는 영어에 대한 기본 설정을 사용하여 미국 영어, 영어 및 칠레 스페인어를 지정합니다.
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
앱의 문화권은 앱의 지원되는 문화권과 일치하는 첫 번째로 요청된 언어를 일치시켜 설정됩니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Startup.Configure(Startup.cs)에서 앱의 지원되는 문화권을 지정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다.
참고
일부 브라우저에서는 요청 및 브라우저의 자체 UI 설정 모두에 대해 강제로 기본 언어 설정을 사용하도록 합니다. 이렇게 하면 모든 설정 UI 화면이 읽을 수 없는 언어로 표시될 수 있으므로 언어를 이해할 수 있는 언어로 변경하는 것이 어려울 수 있습니다. Opera와 같은 브라우저에서는 웹 페이지 요청에 대한 기본 언어를 설정할 수 있지만 브라우저의 설정 UI를 사용 중인 언어로 그대로 둘 수 있으므로 테스트에 적합합니다.
문화권이 미국 영어(en-US)인 경우 렌더링된 구성 요소는 월/일 날짜 서식(6/7), 12시간 형식(AM/PM), 쉼표를 숫자 구분 기호로, 점을 소숫점으로 사용합니다(1,999.69).
- 날짜: 6/7/2021 6:45:22 AM
- 숫자: 1,999.69
문화권이 칠레 스페인어(es-CL)인 경우 렌더링된 구성 요소는 일/월 날짜 서식(7/6), 24시간 형식, 마침표를 숫자 구분 기호로, 쉼표를 소숫점으로 사용합니다(1.999,69).
- 날짜: 7/6/2021 6:49:38
- 숫자: 1.999,69
정적으로 문화권 설정
기본적으로 Blazor WebAssembly 앱에 대한 IL(중간 언어) 링커 구성에서는 명시적으로 요청된 로캘을 제외한 국제화 정보를 제거합니다. 자세한 내용은 ASP.NET Core Blazor용 링커 구성을 참조하세요.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후에 Startup.Configure(Startup.cs)에서 정적 문화권을 지정합니다. 다음 예제에서는 미국 영어를 구성합니다.
app.UseRequestLocalization("en-US");
UseRequestLocalization의 문화권 값은 BCP-47 언어 태그 형식을 준수해야 합니다.
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 세계화의 작동 방식을 알아봅니다. 미국 영어(en-US)를 사용하여 요청을 실행합니다. 브라우저의 언어 설정에서 칠레 스페인어(es-CL)로 전환합니다. 웹 페이지를 다시 요청합니다. 요청된 언어가 칠레 스페인어인 경우 앱의 문화권은 미국 영어(en-US)로 유지됩니다.
사용자 기본 설정에 따라 문화권을 동적으로 설정
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 브라우저 로컬 스토리지를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
Blazor WebAssembly 앱의 앱 문화권은 Blazor 프레임워크의 API를 사용하여 설정됩니다. 사용자의 문화권 선택은 브라우저 로컬 스토리지에 유지할 수 있습니다.
Blazor의 <script> 태그 뒤, 닫는 </body> 태그 앞에 있는 wwwroot/index.html 파일에서 브라우저 로컬 스토리지를 사용하여 사용자의 문화권 선택을 가져오고 설정하기 위한 JS 함수를 제공합니다.
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
System.Globalization 및 Microsoft.JSInterop의 네임스페이스를 Program.cs의 맨 위에 추가합니다.
using System.Globalization;
using Microsoft.JSInterop;
Program.cs에서 다음 줄을 제거합니다.
- await builder.Build().RunAsync();
앞의 줄을 다음 코드로 바꿉니다. 이 코드는 AddLocalization을(를) 사용하여 Blazor의 지역화 서비스를 앱의 서비스 컬렉션에 추가하고 JSinterop을 사용하여 JS으(로) 호출하고 로컬 스토리지에서 사용자의 문화권 선택을 검색합니다. 로컬 스토리지에 사용자에 대한 문화권이 없는 경우 코드는 기본값인 미국 영어(en-US)를 설정합니다.
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
중요
IStringLocalizer 및 IStringLocalizer<T>를 사용하려면 항상 DefaultThreadCurrentCulture 및 DefaultThreadCurrentUICulture를 동일한 문화권으로 설정합니다.
다음 CultureSelector 구성 요소는 JS interop을 통해 사용자의 문화권 선택을 브라우저 로컬 스토리지로 설정하는 방법을 보여 줍니다. 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Nav.NavigateTo(Nav.Uri, forceLoad: true);
}
}
}
}
참고
IJSInProcessRuntime에 대한 자세한 내용은 ASP.NET Core의 .NET 메서드에서 JavaScript 함수 호출Blazor을 참조하세요.
Shared/MainLayout.razor에서 <div class="main"> 요소의 닫는 </div> 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
앱이 사용자의 기본 설정을 저장할 수 있는 위치의 예로는 브라우저 로컬 스토리지(Blazor WebAssembly 앱에서 일반적), 지역화 cookie 또는 데이터베이스(Blazor Server 앱에서 일반적) 또는 외부 데이터베이스에 연결되고 웹 API에서 액세스하는 외부 서비스가 있습니다. 다음 예제에서는 지역화 cookie를 사용하는 방법을 보여 줍니다.
앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
Blazor Server 앱은 지역화 미들웨어를 사용하여 지역화됩니다. AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
RequestLocalizationOptions을 통해 앱의 기본 문화권 및 지원되는 문화권을 설정합니다.
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Startup.Configure에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
다음 예제에서는 지역화 미들웨어에서 읽을 수 있는 cookie의 현재 문화권을 설정하는 방법을 보여 줍니다.
다음 네임스페이스를 Pages/_Host.cshtml 파일 맨 위에 추가합니다.
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Pages/_Host.cshtml의 여는 <body> 태그 바로 다음에 다음 Razor 식을 추가합니다.
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 컨트롤러 작업을 처리하도록 구성되지 않은 경우 다음과 같습니다.
Startup.ConfigureServices의 서비스 컬렉션에서 AddControllers를 호출하여 MVC 서비스를 추가합니다.services.AddControllers();IEndpointRouteBuilder에서 MapControllers를 호출하여
Startup.Configure에 컨트롤러 엔드포인트 라우팅을 추가합니다.endpoints.MapControllers();다음 예제에서는 줄이 추가된 후 UseEndpoints에 대한 호출을 보여 줍니다.
app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
사용자가 문화권을 선택하기 위한 UI를 제공하려면 지역화 cookie에서 리디렉션 기반 접근 방식을 사용합니다. 앱은 컨트롤러에 대한 리디렉션을 통해 사용자가 선택한 문화권을 유지합니다. 컨트롤러는 사용자가 선택한 문화권을 cookie로 설정하고 사용자를 원래 URI로 다시 리디렉션합니다. 이 프로세스는 사용자가 보안 리소스에 액세스하려고 할 때 웹앱에서 발생하는 작업과 비슷합니다. 즉, 사용자는 로그인 페이지로 리디렉션되고 다시 원래 리소스로 리디렉션됩니다.
Controllers/CultureController.cs:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
경고
LocalRedirect 작업 결과를 사용하여 오픈 리디렉션 공격을 방지합니다. 자세한 내용은 ASP.NET Core에서 오픈 리디렉션 공격 방지를 참조하세요.
다음 CultureSelector 구성 요소는 사용자가 문화권을 선택할 때 초기 리디렉션을 수행하는 방법의 예를 보여 줍니다. 구성 요소는 앱 전체에서 사용할 수 있게 Shared 폴더에 배치됩니다.
Shared/CultureSelector.razor:
@using System.Globalization
@inject NavigationManager Nav
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Nav.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Nav.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor에서 <div class="main"> 요소의 닫는 </div> 태그 안에 CultureSelector 구성 요소를 추가합니다.
<div class="bottom-row px-4">
<CultureSelector />
</div>
데모 구성 요소 섹션에 표시되는 CultureExample1 구성 요소를 사용하여 이전 예제의 작동 방식을 알아봅니다.
지역화
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우 앱에 Microsoft.Extensions.Localization 패키지를 추가합니다.
참고
.NET 앱에 패키지를 추가하는 지침은 패키지 사용 워크플로(NuGet 설명서)에서 패키지 설치 및 관리 아래의 문서를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
기본적으로 Blazor WebAssembly 앱에 대한 IL(중간 언어) 링커 구성에서는 명시적으로 요청된 로캘을 제외한 국제화 정보를 제거합니다. 자세한 내용은 ASP.NET Core Blazor용 링커 구성을 참조하세요.
Program.cs에서 System.Globalization의 네임스페이스를 파일 맨 위에 추가합니다.
using System.Globalization;
Program.cs에서 AddLocalization를 사용하여 앱의 서비스 컬렉션에 Blazor의 지역화 서비스를 추가합니다.
builder.Services.AddLocalization();
지역화 미들웨어를 사용하여 앱의 문화권을 설정합니다.
앱이 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션에 따른 문화권 선택을 아직 지원하지 않는 경우:
- AddLocalization을 사용하여 앱에 지역화 서비스를 추가합니다.
Startup.Configure(Startup.cs)에서 앱의 기본 문화권 및 지원되는 문화권을 설정합니다. 다음 예제에서는 미국 영어 및 칠레 스페인어에 대해 지원되는 문화권을 구성합니다.
Startup.ConfigureServices(Startup.cs)에서:
services.AddLocalization();
라우팅 미들웨어가 처리 파이프라인에 추가된 직후 Startup.Configure에서:
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure의 미들웨어 파이프라인에서 지역화 미들웨어를 정렬하는 방법에 대한 내용은 ASP.NET Core 미들웨어를 참조하세요.
앱이 사용자의 문화권 설정 저장에 따라 리소스를 지역화해야 하는 경우 지역화 문화권 cookie를 사용합니다. cookie를 사용하면 WebSocket 연결이 문화권을 올바르게 전파할 수 있게 됩니다. 지역화 체계가 URL 경로 또는 쿼리 문자열을 기준으로 하는 경우 스키마는 WebSocket을 사용하지 못할 수 있으므로 문화권이 유지되지 않습니다. 따라서 지역화 문화권 cookie를 사용하는 것이 좋습니다. 사용자의 문화권 선택을 유지하는 Pages/_Host.cshtml 파일에 대한 예제 Razor 식을 보려면 이 문서의 사용자 기본 설정에 따라 문화권을 동적으로 설정 섹션을 참조하세요.
이 섹션의 지역화된 리소스 예제는 이 문서의 이전 예제에서 작동합니다. 여기서 앱의 지원되는 문화권은 영어(en)를 기본 로케일로 사용하고 스페인어(es)를 사용자가 선택할 수 있거나 브라우저에서 지정되는 대체 로케일로 사용합니다.
각 로케일에 대한 리소스를 만듭니다. 다음 예제에서는 기본 Greeting 문자열에 대한 리소스가 만들어집니다.
- 영어:
Hello, World! - 스페인어(
es):¡Hola, Mundo!
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 Hello, World!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>Hello, World!</value>
</data>
</root>
참고
프로젝트의 Pages 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목>리소스 파일을 선택하여 다음 리소스 파일을 Visual Studio에 추가할 수 있습니다. 파일 이름을 CultureExample2.es.resx로 지정합니다. 편집기가 나타나면 새 항목에 대한 데이터를 제공합니다. 이름을 Greeting으로 설정하고 값을 ¡Hola, Mundo!로 설정합니다. 파일을 저장합니다.
Pages/CultureExample2.es.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>¡Hola, Mundo!</value>
</data>
</root>
다음 구성 요소는 IStringLocalizer<T>와 함께 지역화된 Greeting 문자열을 사용하는 방법을 보여 줍니다. 다음 예제의 Razor 태그 @Loc["Greeting"]은 이전 리소스 파일에 설정된 Greeting 값으로 키가 지정된 문자열을 지역화합니다.
Microsoft.Extensions.Localization에 대한 네임스페이스를 앱의 _Imports.razor 파일에 추가합니다.
@using Microsoft.Extensions.Localization
Pages/CultureExample2.razor:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
필요에 따라 CultureExample2 구성 요소에 대한 Shared/NavMenu.razor의 탐색에 메뉴 항목을 추가합니다.