-
Notifications
You must be signed in to change notification settings - Fork 65
Added support for get culture information from request's route data i… #288
Conversation
…nformation. [Fixes #122] Get segment from mapped route for CustomRequestCultureProvider
Great, looks I need to close my issue #282 because I was planning to make a PR for this, unfortunately no one respond to that issue 😞 |
@@ -0,0 +1,19 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why you're creating a new project for Routing? It will be nice to follow the structure that's already used in the repo. I think adding RouteDataRequestCultureProvider.cs
is appropriate choice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to avoid dependency of Routing in core localization package as it does not depend on routing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Valid point
@@ -0,0 +1,21 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here add we can adds the test to the Microsoft.AspNetCore.Localization.Tests
project
Can we add this to the https://github.com/aspnet/Localization/tree/dev/test/LocalizationWebsite for functional test, because what you did in the unit tests that you wrote is to configure the localization options inside |
new CultureInfo("ar-YE") | ||
} | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can replace it with
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider()
{
Options = options,
RouteDataStringKey = "c",
UIRouteDataStringKey = "uic"
});
new CultureInfo("ar-YE") | ||
} | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify this with
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider()
{
Options = options
});
{ | ||
DefaultRequestCulture = new RequestCulture("en-US") | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as my previous suggestion
It's also possible to register the newly |
|
||
if (!string.IsNullOrWhiteSpace(RouteDataStringKey)) | ||
{ | ||
culture = httpContext.GetRouteValue(RouteDataStringKey) as string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use ToString()
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new CultureInfo("ar-YE") | ||
} | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as previous suggestion
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
var data = await response.Content.ReadAsStringAsync(); | ||
Assert.Equal($"{expectedCulture},{expectedUICulture}", data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pleas add new line here
{ | ||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>(); | ||
var requestCulture = requestCultureFeature.RequestCulture; | ||
return context.Response.WriteAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
new CultureInfo("ar-YE") | ||
} | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
var data = await response.Content.ReadAsStringAsync(); | ||
Assert.Equal("en-US,en-US", data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
{ | ||
DefaultRequestCulture = new RequestCulture("en-US") | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
var data = await response.Content.ReadAsStringAsync(); | ||
Assert.Equal($"{expectedCulture},{expectedUICulture}", data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
{ | ||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>(); | ||
var requestCulture = requestCultureFeature.RequestCulture; | ||
return context.Response.WriteAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
new CultureInfo("ar-YE") | ||
} | ||
}; | ||
options.RequestCultureProviders = new[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add new line here
using Microsoft.AspNetCore.TestHost; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Xunit; | ||
using System.Net; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please sort the namesapces
if (culture == null && uiCulture == null) | ||
{ | ||
// No values specified for either so no match | ||
return Task.FromResult((ProviderCultureResult)null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Microsoft.Extensions.TaskCache.Sources
to avoid creating this Task
in every request.
/// <see cref="RouteDataStringKey"/> will be used. | ||
/// Defaults to "ui-culture". | ||
/// </summary> | ||
public string UIRouteDataStringKey { get; set; } = "ui-culture"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a new options class
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Experience here is in line with existing culture providers. So I do not want to do anything different with this new provider.
Adding the new provider in the linked location would cause that package to indirectly depend on Routing which we want to avoid. |
If you take a look at the website, it does not depend on MVC (this is on purpose as in our build process we do not want to create a circular dependency between repositories). For the scenario you mentioned, I am planning to update an existing test in MVC which tests the scenario you mentioned: https://github.com/aspnet/Mvc/blob/dev/test/WebSites/FiltersWebSite/LocalizationPipeline.cs#L27 |
🆙 📅 |
|
||
if (!string.IsNullOrWhiteSpace(RouteDataStringKey)) | ||
{ | ||
culture = httpContext.GetRouteValue(RouteDataStringKey) as string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"dependencies": { | ||
"Microsoft.AspNetCore.Localization": "1.1.0-*", | ||
"Microsoft.AspNetCore.Routing": "1.1.0-*", | ||
"Microsoft.Extensions.TaskCache.Sources": "1.1.0-*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must be a "type": "build"
dependency.
@@ -23,7 +23,8 @@ | |||
"Microsoft.AspNetCore.Http.Extensions": "1.1.0-*", | |||
"Microsoft.Extensions.Globalization.CultureInfoCache": "1.1.0-*", | |||
"Microsoft.Extensions.Localization.Abstractions": "1.1.0-*", | |||
"Microsoft.Extensions.Options": "1.1.0-*" | |||
"Microsoft.Extensions.Options": "1.1.0-*", | |||
"Microsoft.Extensions.TaskCache.Sources": "1.1.0-*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"type": "build"
string culture = null; | ||
string uiCulture = null; | ||
|
||
if (!string.IsNullOrWhiteSpace(RouteDataStringKey)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't check white space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description provided.
🆙 📅 |
@@ -33,7 +34,7 @@ public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpC | |||
|
|||
if (acceptLanguageHeader == null || acceptLanguageHeader.Count == 0) | |||
{ | |||
return Task.FromResult((ProviderCultureResult)null); | |||
return TaskCache<ProviderCultureResult>.DefaultCompletedTask; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this change applicable in this PR, or may we need another PR, while this one specially for adding RouteDataCulureRequestProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ | ||
app.UseRouter(routes => | ||
{ | ||
routes.MapRoute(routeTemplate, (IApplicationBuilder fork) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fork
??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can subApp instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do call this a forked pipeline. But subApp
is also commonly used.
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>(); | ||
var requestCulture = requestCultureFeature.RequestCulture; | ||
return context.Response.WriteAsync( | ||
$"{requestCulture.Culture.Name},{requestCulture.UICulture.Name}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: lessen the indenting
{ | ||
app.UseRouter(routes => | ||
{ | ||
routes.MapRoute(routeTemplate, (IApplicationBuilder fork) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fork
??
|
||
namespace Microsoft.AspNetCore.Localization.Routing | ||
{ | ||
public class RouteDataRequestCultureProviderTest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 3 tests in this class seem to share a lot of boilerplate. Can any of that be moved into helper methods to reduce the repetition and make the differences between the setups more obvious?
…nformation.
[Fixes #122] Get segment from mapped route for CustomRequestCultureProvider
@Eilon