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);
}
}