In the startup ConfigureServices, register the services needed for localization: AddLocalization and Configure<RequestLocalizationOptions>
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization();
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-us"),
new CultureInfo("zh-cn")
};
options.DefaultRequestCulture = new RequestCulture(culture: "en-us", uiCulture: "en-us");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new IRequestCultureProvider[] { new RouteDataRequestCultureProvider { IndexOfCulture = 1, IndexofUiCulture = 1 } };
});
services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("culture", typeof(LanguageRouteConstraint));
});
services.AddControllers();
}
Add the request localization middleware in the Configure method of the Startup.cs class.
var localizeOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(localizeOptions.Value);
RequestCultureProvider uses a simple delegate to determine the current localized culture. Of course, we can also customize the source of request culture information via RequestCultureProvider, such as configuration files or databases. Or we can choose some default ways to obtain the current region.
ASP.NET Core localization provides us with four default methods to determine the current culture of the executing request:
- QueryStringRequestCultureProvider
- CookieRequestCultureProvider
- AcceptLanguageHeaderRequestCultureProvider
- CustomRequestCultureProvider
As shown below, I will determine the current region via routing.
public class RouteDataRequestCultureProvider : RequestCultureProvider
{
public int IndexOfCulture;
public int IndexofUiCulture;
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
string uiCulture;
string culture = uiCulture = httpContext.Request.Path.Value.Split('/')[IndexOfCulture];
var providerResultCulture = new ProviderCultureResult(culture, uiCulture);
return Task.FromResult(providerResultCulture);
}
}
Through the following code snippet, implement IRouteConstraint to constrain the route accordingly.
public class LanguageRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (!values.ContainsKey("culture"))
return false;
var culture = values["culture"].ToString();
return culture == "en-us" || culture == "zh-cn";
}
}
Add regional resource files.

[Route("{culture:culture}/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IStringLocalizer<Resource> localizer;
public HomeController(IStringLocalizer<Resource> localizer)
{
this.localizer = localizer;
}
public string Get()
{
return localizer["Home"];
}
}

Reference:https://github.com/hueifeng/BlogSample/tree/master/src/LocalizationSingleResx