2 Comments

I already wrote few blog posts about the localization in ASP.NET Core, it will be nice to use the localization with another ASP.NET Core components.

Today I'm gonna talk about localization & routing hand on hand, ASP.NET Core already have a middleware for routing the requests to application logic, for more details you can look to the routing repository.

As we know from my post about Localization Extensibility in ASP.NET Core 1.0 that localization is shipped with four request culture providers, and I remembered that I post an issue for support DomainRequestCultureProvider also there's another issue to Get segment from mapped route for CustomRequestCultureProvider with that I realize that there's a need for such RequestCultureProvider to get the culture information from the route data.

Almost of us know that we can easily get data from the routing whenever we have  HttpContext object, using the method GetRouteValue, so with that let us create our provider.

Easily we can take the source code for the QueryStringRequestCultureProvider and modify it little bit to accomplish our goal.

public class RouteDataRequestCultureProvider : RequestCultureProvider
{
public string RouteDataKey { get; set; } = "culture";

public string UIRouteDataKey { get; set; } = "ui-culture";

public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}

string culture = null;
string uiCulture = null;

if (!string.IsNullOrWhiteSpace(RouteDataKey))
{
culture = httpContext.GetRouteValue(RouteDataKey);
}

if (!string.IsNullOrWhiteSpace(UIRouteDataKey))
{
uiCulture = httpContext.GetRouteValue(UIRouteDataKey);
}

if (culture == null && uiCulture == null)
{
return Task.FromResult((ProviderCultureResult)null);
}

if (culture != null && uiCulture == null)
{
uiCulture = culture;
}

if (culture == null && uiCulture != null)
{
culture = uiCulture;
}

var providerResultCulture = new ProviderCultureResult(culture, uiCulture);

return Task.FromResult(providerResultCulture);
}
}

The code is straightforward nothing fancy except we getting the route data values from the HttpContext as I mentioned before.

We're done!! after that we can you use our provider like the following:

public void Configure(IApplicationBuilder app, IStringLocalizer<startup> localizer)
{
var supportedCultures = new List<cultureinfo>
{
new CultureInfo("en-US"),
new CultureInfo("ar-SA")
};

var options = new RequestLocalizationOptions()
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
};

options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
app.UseRequestLocalization(options);
...
}