Skip to content

Commit b041a07

Browse files
committed
Change culture fallback to depth-first:
- #112
1 parent e72d3cb commit b041a07

File tree

2 files changed

+35
-41
lines changed

2 files changed

+35
-41
lines changed

src/Microsoft.AspNet.Localization/RequestLocalizationMiddleware.cs

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,15 @@ public async Task Invoke(HttpContext context)
7878
cultureInfo = GetCultureInfo(
7979
cultures,
8080
_options.SupportedCultures,
81-
_options.FallBackToParentCultures,
82-
currentDepth: 0);
81+
_options.FallBackToParentCultures);
8382
}
8483

8584
if (_options.SupportedUICultures != null)
8685
{
8786
uiCultureInfo = GetCultureInfo(
8887
uiCultures,
8988
_options.SupportedUICultures,
90-
_options.FallBackToParentUICultures,
91-
currentDepth: 0);
89+
_options.FallBackToParentUICultures);
9290
}
9391

9492
if (cultureInfo == null && uiCultureInfo == null)
@@ -139,57 +137,47 @@ private static void SetCurrentThreadCulture(RequestCulture requestCulture)
139137
private static CultureInfo GetCultureInfo(
140138
IList<string> cultureNames,
141139
IList<CultureInfo> supportedCultures,
142-
bool fallbackToAncestorCulture,
143-
int currentDepth)
140+
bool fallbackToAncestorCulture)
144141
{
145142
foreach (var cultureName in cultureNames)
146143
{
147144
// Allow empty string values as they map to InvariantCulture, whereas null culture values will throw in
148145
// the CultureInfo ctor
149146
if (cultureName != null)
150147
{
151-
var cultureInfo = CultureInfoCache.GetCultureInfo(cultureName, supportedCultures);
148+
var cultureInfo = GetCultureInfo(cultureName, supportedCultures, fallbackToAncestorCulture, currentDepth: 0);
152149
if (cultureInfo != null)
153150
{
154151
return cultureInfo;
155152
}
156153
}
157154
}
158155

159-
if (fallbackToAncestorCulture & currentDepth < MaxCultureFallbackDepth)
156+
return null;
157+
}
158+
159+
private static CultureInfo GetCultureInfo(
160+
string cultureName,
161+
IList<CultureInfo> supportedCultures,
162+
bool fallbackToAncestorCulture,
163+
int currentDepth)
164+
{
165+
var culture = CultureInfoCache.GetCultureInfo(cultureName, supportedCultures);
166+
167+
if (culture == null && fallbackToAncestorCulture && currentDepth < MaxCultureFallbackDepth)
160168
{
161-
// Walk backwards through the culture list and remove any root cultures (those with no parent)
162-
for (var i = cultureNames.Count - 1; i >= 0; i--)
163-
{
164-
var cultureName = cultureNames[i];
165-
if (cultureName != null)
166-
{
167-
var lastIndexOfHyphen = cultureName.LastIndexOf('-');
168-
if (lastIndexOfHyphen > 0)
169-
{
170-
// Trim the trailing section from the culture name, e.g. "fr-FR" becomes "fr"
171-
cultureNames[i] = cultureName.Substring(0, lastIndexOfHyphen);
172-
}
173-
else
174-
{
175-
// The culture had no sections left to trim so remove it from the list of candidates
176-
cultureNames.RemoveAt(i);
177-
}
178-
}
179-
else
180-
{
181-
// Culture name was null so just remove it
182-
cultureNames.RemoveAt(i);
183-
}
184-
}
169+
var lastIndexOfHyphen = cultureName.LastIndexOf('-');
185170

186-
if (cultureNames.Count > 0)
171+
if (lastIndexOfHyphen > 0)
187172
{
188-
return GetCultureInfo(cultureNames, supportedCultures, fallbackToAncestorCulture, currentDepth + 1);
173+
// Trim the trailing section from the culture name, e.g. "fr-FR" becomes "fr"
174+
var parentCultureName = cultureName.Substring(0, lastIndexOfHyphen);
175+
176+
culture = GetCultureInfo(parentCultureName, supportedCultures, fallbackToAncestorCulture, currentDepth + 1);
189177
}
190178
}
191179

192-
return null;
180+
return culture;
193181
}
194182
}
195183
}

src/Microsoft.AspNet.Localization/RequestLocalizationOptions.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,34 @@ public RequestCulture DefaultRequestCulture
5151
}
5252

5353
/// <summary>
54-
/// Gets or sets a value indicating whether to set a request culture to an ancestor culture in the case the
54+
/// Gets or sets a value indicating whether to set a request culture to an parent culture in the case the
5555
/// culture determined by the configured <see cref="IRequestCultureProvider"/>s is not in the
56-
/// <see cref="SupportedCultures"/> list but an ancestor culture is.
56+
/// <see cref="SupportedCultures"/> list but a parent culture is.
5757
/// Defaults to <c>true</c>;
5858
/// </summary>
59+
/// <remarks>
60+
/// Note that the parent culture check is done using only the culture name.
61+
/// </remarks>
5962
/// <example>
6063
/// If this property is <c>true</c> and the application is configured to support the culture "fr", but not the
6164
/// culture "fr-FR", and a configured <see cref="IRequestCultureProvider"/> determines a request's culture is
62-
/// "fr-FR", then the request's culture will be set to the culture "fr", as it is an ancestor of "fr-FR".
65+
/// "fr-FR", then the request's culture will be set to the culture "fr", as it is a parent of "fr-FR".
6366
/// </example>
6467
public bool FallBackToParentCultures { get; set; } = true;
6568

6669
/// <summary>
67-
/// Gets or sets a value indicating whether to set a request UI culture to an ancestor culture in the case the
70+
/// Gets or sets a value indicating whether to set a request UI culture to a parent culture in the case the
6871
/// UI culture determined by the configured <see cref="IRequestCultureProvider"/>s is not in the
69-
/// <see cref="SupportedUICultures"/> list but an ancestor culture is.
72+
/// <see cref="SupportedUICultures"/> list but a parent culture is.
7073
/// Defaults to <c>true</c>;
7174
/// </summary>
75+
/// <remarks>
76+
/// Note that the parent culture check is done using ony the culture name.
77+
/// </remarks>
7278
/// <example>
7379
/// If this property is <c>true</c> and the application is configured to support the UI culture "fr", but not
7480
/// the UI culture "fr-FR", and a configured <see cref="IRequestCultureProvider"/> determines a request's UI
75-
/// culture is "fr-FR", then the request's UI culture will be set to the culture "fr", as it is an ancestor of
81+
/// culture is "fr-FR", then the request's UI culture will be set to the culture "fr", as it is a parent of
7682
/// "fr-FR".
7783
/// </example>
7884
public bool FallBackToParentUICultures { get; set; } = true;

0 commit comments

Comments
 (0)