Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the .NET and .NET Core Support Policy. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
Hisham Bin Ateya, Damien Bowden, Bart Calixto, Nadeem Afana, and Rick Anderson
One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns.
The current culture on a request is set in the localization Middleware. The localization middleware is enabled in Program.cs
. The localization middleware must be configured before any middleware that might check the request culture (for example, app.UseMvcWithDefaultRoute()
).
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[] { "en-US", "fr" };
options.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
});
UseRequestLocalization initializes a RequestLocalizationOptions object. On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. The default providers come from the RequestLocalizationOptions
class:
The default list goes from most specific to least specific. Later in the article you'll see how you can change the order and even add a custom culture provider. If none of the providers can determine the request culture, the DefaultRequestCulture is used.
Some apps will use a query string to set the CultureInfo. For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider
list. You pass the query string parameters culture
and ui-culture
. The following example sets the specific culture (language and region) to Spanish/Mexico:
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
If only culture
or ui-culture
is passed in, the query string provider sets both values using the one passed in. For example, setting just the culture will set both the Culture
and the UICulture
:
http://localhost:5000/?culture=es-MX
Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Use the MakeCookieValue method to create a cookie.
The CookieRequestCultureProvider DefaultCookieName returns the default cookie name used to track the user's preferred culture information. The default cookie name is .AspNetCore.Culture
.
The cookie format is c=%LANGCODE%|uic=%LANGCODE%
, where c
is Culture
and uic
is UICulture
, for example:
c=en-UK|uic=en-US
If only one of the cultures is provided and the other is empty, the provided culture is used for both culture and UI culture.
The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. This setting indicates what the browser has been set to send or has inherited from the underlying operating system. The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). A production app should include a way for a user to customize their choice of culture.
Search Settings for Preferred languages.
The preferred languages are listed in the Preferred languages box.
Select Add languages to add to the list.
Select More actions … next to a language to change the order of preference.
The Content-Language entity header:
Entity headers are used in both HTTP requests and responses.
The Content-Language
header can be added by setting the property ApplyCurrentCultureToResponseHeaders.
Adding the Content-Language
header:
Content-Language
header with the CurrentUICulture
.Content-Language
explicitly.app.UseRequestLocalization(new RequestLocalizationOptions
{
ApplyCurrentCultureToResponseHeaders = true
});
The RouteDataRequestCultureProvider sets the culture based on the value of the culture
route value. See Url culture provider using middleware as filters for information on:
RouteDataRequestCultureProvider
to set the culture of an app from the url.See Applying the RouteDataRequest CultureProvider globally with middleware as filters for information on how to apply the RouteDataRequestCultureProvider
globally.
Suppose you want to let your customers store their language and culture in your databases. You could write a provider to look up these values for the user. The following code shows how to add a custom provider:
private const string enUSCulture = "en-US";
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo(enUSCulture),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
// My custom request culture logic
return await Task.FromResult(new ProviderCultureResult("en"));
}));
});
Use RequestLocalizationOptions
to add or remove localization providers.
RequestLocalizationOptions has three default request culture providers: QueryStringRequestCultureProvider, CookieRequestCultureProvider, and AcceptLanguageHeaderRequestCultureProvider. Use RequestLocalizationOptions.RequestCultureProviders
property to change the order of these providers as shown in the following below:
app.UseRequestLocalization(options =>
{
var questStringCultureProvider = options.RequestCultureProviders[0];
options.RequestCultureProviders.RemoveAt(0);
options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});
In the preceding example, the order of QueryStringRequestCultureProvider
and CookieRequestCultureProvider
is switched, so the RequestLocalizationMiddleware
looks for the cultures from the cookies first, then the query string.
As previously mentioned, add a custom provider via AddInitialRequestCultureProvider which sets the order to 0
, so this provider takes the precedence over the others.
The RequestLocalizationOptions.CultureInfoUseUserOverride property allows the app to decide whether or not to use non-default Windows settings for the CultureInfo DateTimeFormat and NumberFormat properties. This has no impact on Linux. This directly corresponds to UseUserOverride.
app.UseRequestLocalization(options =>
{
options.CultureInfoUseUserOverride = false;
});
This sample Localization.StarterWeb project on GitHub contains UI to set the Culture
. The Views/Shared/_SelectLanguagePartial.cshtml
file allows you to select the culture from the list of supported cultures:
@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>
The Views/Shared/_SelectLanguagePartial.cshtml
file is added to the footer
section of the layout file so it will be available to all views:
<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>
The SetLanguage
method sets the culture cookie.
[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);
}
You can't plug in the _SelectLanguagePartial.cshtml
to sample code for this project. The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions
to a Razor partial through the Dependency Injection container.
See Globalization behavior of model binding route data and query strings.
Localizing an app also involves the following tasks:
Hisham Bin Ateya, Damien Bowden, Bart Calixto, Nadeem Afana, and Rick Anderson
One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns.
The current culture on a request is set in the localization Middleware. The localization middleware is enabled in Program.cs
. The localization middleware must be configured before any middleware that might check the request culture (for example, app.UseMvcWithDefaultRoute()
).
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[] { "en-US", "fr" };
options.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
});
UseRequestLocalization initializes a RequestLocalizationOptions object. On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. The default providers come from the RequestLocalizationOptions
class:
The default list goes from most specific to least specific. Later in the article you'll see how you can change the order and even add a custom culture provider. If none of the providers can determine the request culture, the DefaultRequestCulture is used.
Some apps will use a query string to set the CultureInfo. For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider
list. You pass the query string parameters culture
and ui-culture
. The following example sets the specific culture (language and region) to Spanish/Mexico:
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
If only culture
or ui-culture
is passed in, the query string provider sets both values using the one passed in. For example, setting just the culture will set both the Culture
and the UICulture
:
http://localhost:5000/?culture=es-MX
Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Use the MakeCookieValue method to create a cookie.
The xref:Microsoft.AspNetCore.Localization.CookieRequestCultureProvider> DefaultCookieName returns the default cookie name used to track the user's preferred culture information. The default cookie name is .AspNetCore.Culture
.
The cookie format is c=%LANGCODE%|uic=%LANGCODE%
, where c
is Culture
and uic
is UICulture
, for example:
c=en-UK|uic=en-US
If only one of culture info or UI culture is provided, the provided culture is used for both culture info and UI culture.
The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. This setting indicates what the browser has been set to send or has inherited from the underlying operating system. The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). A production app should include a way for a user to customize their choice of culture.
Search Settings for Preferred languages.
The preferred languages are listed in the Preferred languages box.
Select Add languages to add to the list.
Select More actions … next to a language to change the order of preference.
The Content-Language entity header:
Entity headers are used in both HTTP requests and responses.
The Content-Language
header can be added by setting the property ApplyCurrentCultureToResponseHeaders.
Adding the Content-Language
header:
Content-Language
header with the CurrentUICulture
.Content-Language
explicitly.app.UseRequestLocalization(new RequestLocalizationOptions
{
ApplyCurrentCultureToResponseHeaders = true
});
Suppose you want to let your customers store their language and culture in your databases. You could write a provider to look up these values for the user. The following code shows how to add a custom provider:
private const string enUSCulture = "en-US";
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo(enUSCulture),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
// My custom request culture logic
return await Task.FromResult(new ProviderCultureResult("en"));
}));
});
Use RequestLocalizationOptions
to add or remove localization providers.
RequestLocalizationOptions has three default request culture providers: QueryStringRequestCultureProvider, CookieRequestCultureProvider, and AcceptLanguageHeaderRequestCultureProvider. Use RequestLocalizationOptions.RequestCultureProviders
property to change the order of these providers as shown in the following below:
app.UseRequestLocalization(options =>
{
var questStringCultureProvider = options.RequestCultureProviders[0];
options.RequestCultureProviders.RemoveAt(0);
options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});
In the preceding example, the order of QueryStringRequestCultureProvider
and CookieRequestCultureProvider
is switched, so the RequestLocalizationMiddleware
looks for the cultures from the cookies first, then the query string.
As previously mentioned, add a custom provider via AddInitialRequestCultureProvider which sets the order to 0
, so this provider takes the precedence over the others.
This sample Localization.StarterWeb project on GitHub contains UI to set the Culture
. The Views/Shared/_SelectLanguagePartial.cshtml
file allows you to select the culture from the list of supported cultures:
@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>
The Views/Shared/_SelectLanguagePartial.cshtml
file is added to the footer
section of the layout file so it will be available to all views:
<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>
The SetLanguage
method sets the culture cookie.
[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);
}
You can't plug in the _SelectLanguagePartial.cshtml
to sample code for this project. The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions
to a Razor partial through the Dependency Injection container.
See Globalization behavior of model binding route data and query strings.
Localizing an app also involves the following tasks:
By Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana, and Hisham Bin Ateya
One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns.
The current culture on a request is set in the localization Middleware. The localization middleware is enabled in the Startup.Configure
method. The localization middleware must be configured before any middleware that might check the request culture (for example, app.UseMvcWithDefaultRoute()
).
var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
UseRequestLocalization
initializes a RequestLocalizationOptions
object. On every request the list of RequestCultureProvider
in the RequestLocalizationOptions
is enumerated and the first provider that can successfully determine the request culture is used. The default providers come from the RequestLocalizationOptions
class:
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
The default list goes from most specific to least specific. Later in the article you'll see how you can change the order and even add a custom culture provider. If none of the providers can determine the request culture, the DefaultRequestCulture
is used.
Some apps will use a query string to set the CultureInfo. For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. By default, the QueryStringRequestCultureProvider
is registered as the first localization provider in the RequestCultureProvider
list. You pass the query string parameters culture
and ui-culture
. The following example sets the specific culture (language and region) to Spanish/Mexico:
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
If you only pass in one of the two (culture
or ui-culture
), the query string provider will set both values using the one you passed in. For example, setting just the culture will set both the Culture
and the UICulture
:
http://localhost:5000/?culture=es-MX
Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Use the MakeCookieValue
method to create a cookie.
The CookieRequestCultureProvider
DefaultCookieName
returns the default cookie name used to track the user's preferred culture information. The default cookie name is .AspNetCore.Culture
.
The cookie format is c=%LANGCODE%|uic=%LANGCODE%
, where c
is Culture
and uic
is UICulture
, for example:
c=en-UK|uic=en-US
If you only specify one of culture info and UI culture, the specified culture will be used for both culture info and UI culture.
The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. This setting indicates what the browser has been set to send or has inherited from the underlying operating system. The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). A production app should include a way for a user to customize their choice of culture.
Search Settings for Preferred languages.
The preferred languages are listed in the Preferred languages box.
Select Add languages to add to the list.
Select More actions … next to a language to change the order of preference.
The Content-Language entity header:
Entity headers are used in both HTTP requests and responses.
The Content-Language
header can be added by setting the property ApplyCurrentCultureToResponseHeaders
.
Adding the Content-Language
header:
Content-Language
header with the CurrentUICulture
.Content-Language
explicitly.app.UseRequestLocalization(new RequestLocalizationOptions
{
ApplyCurrentCultureToResponseHeaders = true
});
Suppose you want to let your customers store their language and culture in your databases. You could write a provider to look up these values for the user. The following code shows how to add a custom provider:
private const string enUSCulture = "en-US";
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo(enUSCulture),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
// My custom request culture logic
return await Task.FromResult(new ProviderCultureResult("en"));
}));
});
Use RequestLocalizationOptions
to add or remove localization providers.
RequestLocalizationOptions has three default request culture providers: QueryStringRequestCultureProvider, CookieRequestCultureProvider, and AcceptLanguageHeaderRequestCultureProvider. Use RequestLocalizationOptions.RequestCultureProviders
property to change the order of these providers as shown in the following below:
app.UseRequestLocalization(options =>
{
var questStringCultureProvider = options.RequestCultureProviders[0];
options.RequestCultureProviders.RemoveAt(0);
options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});
In the preceding example, the order of QueryStringRequestCultureProvider
and CookieRequestCultureProvider
is switched, so the RequestLocalizationMiddleware
looks for the cultures from the cookies first, then the query string.
As previously mentioned, add a custom provider via AddInitialRequestCultureProvider which sets the order to 0
, so this provider takes the precedence over the others.
This sample Localization.StarterWeb project on GitHub contains UI to set the Culture
. The Views/Shared/_SelectLanguagePartial.cshtml
file allows you to select the culture from the list of supported cultures:
@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>
The Views/Shared/_SelectLanguagePartial.cshtml
file is added to the footer
section of the layout file so it will be available to all views:
<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>
The SetLanguage
method sets the culture cookie.
[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);
}
You can't plug in the _SelectLanguagePartial.cshtml
to sample code for this project. The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions
to a Razor partial through the Dependency Injection container.
See Globalization behavior of model binding route data and query strings.
Localizing an app also involves the following tasks:
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreTraining
Module
Customize ASP.NET Core behavior with middleware - Training
Understand and implement middleware in an ASP.NET Core app. Use included middleware like HTTP logging and authentication. Create custom middleware to handle requests and responses.
Documentation
Make an ASP.NET Core app's content localizable
Learn how to make an ASP.NET Core app's content localizable to prepare the app for localizing content into different languages and cultures.
Provide localized resources for languages and cultures in an ASP.NET Core app
Learn how to provide localized resources for localizing content of an ASP.NET Core app into different languages and cultures.
Configure portable object localization in ASP.NET Core
This article introduces Portable Object files and outlines steps for using them in an ASP.NET Core application with the Orchard Core framework.