This is my route:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "defaultWithCulture",
template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}");
});
but localization works when I use the link:
http://localhost:1776/fa-IR/Home/About?culture=fa-ir
but not when
http://localhost:1776/fa-IR/Home/About
why doesn't the culture in the route apply?
SSA's answer didn't solve my problem but gave me a big clue, and finally I got it to work.
The thing to do is:
- As SSA said asp.net core has following RequestCultureProviders, in order. First non-null will be used.
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
So we must change the order of them and add the Routing to be the first:
services.Configure<RequestLocalizationOptions>(
options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR"),
};
options.DefaultRequestCulture = new RequestCulture(culture: "fa-IR", uiCulture: "fa-IR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Clear();
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider();
options.RequestCultureProviders.Insert(1, new QueryStringRequestCultureProvider());
options.RequestCultureProviders.Insert(2, new CookieRequestCultureProvider());
options.RequestCultureProviders.Insert(3, new AcceptLanguageHeaderRequestCultureProvider());
services.AddSingleton(options);
});
2- When RouteDataRequestCultureProvider Task executed, still the RoutingData is null and is not given a value yet, so it will always return null, so I changed it like Below to use the Url.Path
instead of RoutingData:
public class RouteDataRequestCultureProvider : RequestCultureProvider
{
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
string culture = null;
string uiCulture = null;
uiCulture = culture = httpContext.Request.Path.Value.Split('/')[1]?.ToString();
if (culture == null)
{
return TaskCache<ProviderCultureResult>.DefaultCompletedTask;
}
var providerResultCulture = new ProviderCultureResult(culture, uiCulture);
return Task.FromResult(providerResultCulture);
}
}
As far as I know, asp.net core has following RequestCultureProviders, in order. First non-null will be used.
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
and you need to add RouteDataRequestCultureProvider to support culture from route data.
taking an example from here:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("en-GB"),
new CultureInfo("de"),
new CultureInfo("fr-FR"),
};
var options = new RequestLocalizationOptions()
{
DefaultRequestCulture = new RequestCulture(culture: "en-GB", uiCulture: "en-GB"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
};
options.RequestCultureProviders = new[]
{
new RouteDataRequestCultureProvider() { Options = options }
};
services.AddSingleton(options);
}