|
|
|
Joined: 6/20/2004
Posts: 5
|
|
|
Hi,
First of all I'd like to point out that my definitions of country code and so on might be wrong, hope you get the general idea though
I just came over a problem using dnn, where the browser language settings were set to "no" (Norwegian). For some reason, norwegian browsers are setup language-wise using just this country code. The other two locale codes for Norway are: nb-NO, nn-NO. As you can see, the country code comes after the dash, instead of before (in all other locales, like en-US, en-GB), which makes dnn default in another language.
Seems like norway messed up their culture names, compared to everyone else ;) Here's a link to msdn on culture names.
The code below (from PageBase.vb, PageCulture() property) checks for "no" from the browser, then re-assigns ci to equal "nb-NO", which is the most common language in Norway.
' Check if locale is still supported Dim myLocaleCollection As LocaleCollection = Services.Localization.Localization.GetSupportedLocales()
If myLocaleCollection.Item(ci.Name) Is Nothing Then Dim i As Integer
'get the first part of the locale in the collection, locale is of form xx-XX where xx = language 'this is to make sure that no locale is available with the same language as the prefered language of the anonymous user 'the prefered language might just be the language without the country (ie. en, nl, de) 'get the first part of the locale in the collection 'and check against the first part of the prefered locale 'this is to check whether the first part (xx) is part of the collection 'ie en-GB is not available, but en-US is, then new locale will be en-US
For i = 0 To myLocaleCollection.Count - 1 If Split(Convert.ToString(myLocaleCollection.Item(i).Key), "-")(0) = Split(ci.Name.ToString, "-")(0) Then ci = New CultureInfo(Convert.ToString(myLocaleCollection.Item(i).Key)) Return ci Exit Property End If Next
' ************ START NEW CODE ************ If ci.Name.ToString = "no" Then ci = New CultureInfo("nb-NO") Return ci End If ' ************** END NEW CODE **************
'No locale found in the collection, so revert back to system fallback locale ci = New CultureInfo(Convert.ToString(Services.Localization.Localization.SystemLocale)) End If
I'd say this is a fairly serious problem, due to the fact that norwegian IE defaults to "no" instead of "nb-NO" or "nn-NO", and since PageCulture() assumes the format to have been "no-NB" and "no-NN".
Thank you for your time
Regards,
John Frey
|
|
|
|
| |
|
|
|
John,
you're right on your diagnose. The problem is I don't like introducing "special" cases in code just to solve one issue. In fact we don't have any guarantee that this doesn't happen in other languages as well.
Seems "no" is taken as a short for "nb-NO" instead of using "nb" which is the standard in all other cases. And this is not only a browser setting, since .net framework also defines it this way.
Question is should we consider this really a single exception or are more of them? From the code list on msdn it seems it's the only one (both in asp.net 1.1 and 2.0). But I'm not sure whether a specific browser may be doing similar things with some other languages.
Vicenç Masanas
Banyoles, Girona - Spain
|
|
|
|
| |
|
|
Joined: 7/28/2005
Posts: 3
|
|
|
Hi John,
The problem is in the way DNN processes culture codes. It is simply incorrect and ignores built functionality of .NET CultureInfo class. While most of culture codes follow the rule LanguageCode-CountryCode, it is not always true. If you, for example, run the following code:
using System; using System.Globalization; namespace Localization_ParentCultures { class SamplesCultureInfo { [STAThread] static void Main(string[] args) { Console.WriteLine( "Culture\tParent" ); foreach ( CultureInfo ci in CultureInfo.GetCultures( CultureTypes.SpecificCultures ) ) { Console.WriteLine( "{0}\t{1}", ci.Name, ci.Parent.Name ); } } } }
you will see some special cases, specially for chinese and norvegian cultures
Culture: Parent: zh-TW zh-CHT zh-CN zh-CHS zh-HK zh-CHT zh-SG zh-CHS zh-MO zh-CHS nb-NO no nn-NO no
To prevent such problems, we should use Parent property of CultureInfo instead of just splitting strings.
My proposal is to replace the following code in PageBase.PageCulture:
If myLocaleCollection.Item(ci.Name) Is Nothing Then Dim i As Integer 'get the first part of the locale in the collection, locale is of form xx-XX where xx = language 'this is to make sure that no locale is available with the same language as the prefered language of the anonymous user 'the prefered language might just be the language without the country (ie. en, nl, de) 'get the first part of the locale in the collection 'and check against the first part of the prefered locale 'this is to check whether the first part (xx) is part of the collection 'ie en-GB is not available, but en-US is, then new locale will be en-US For i = 0 To myLocaleCollection.Count - 1 If Split(Convert.ToString(myLocaleCollection.Item(i).Key), "-")(0) = Split(ci.Name.ToString, "-")(0) Then ci = New CultureInfo(Convert.ToString(myLocaleCollection.Item(i).Key)) Return ci Exit Property End If Next 'No locale found in the collection, so revert back to system fallback locale ci = New CultureInfo(Convert.ToString(Services.Localization.Localization.SystemLocale)) End If
with this one:
If myLocaleCollection.Item(ci.Name) Is Nothing Then Dim i As Integer Dim ciTemp As CultureInfo 'get the parent of the locale in the collection 'this is to make sure that no locale is available with the same language as the prefered language of the anonymous user 'the prefered language might just be the language without the country (ie. en, nl, de) 'get the parent of the locale in the collection 'and check against the prefered locale and against the parent of prefered locale 'this is to check whether the parent is part of the collection 'ie en-GB is not available, but en-US is, then new locale will be en-US For i = 0 To myLocaleCollection.Count - 1 ciTemp = New CultureInfo(Convert.ToString(myLocaleCollection.Item(i).Key)) If ciTemp.Parent.Equals(ci) Or ciTemp.Parent.Equals(ci.Parent) Then Return ciTemp Exit Property End If Next 'No locale found in the collection, so revert back to system fallback locale ci = New CultureInfo(Convert.ToString(Services.Localization.Localization.SystemLocale)) End If
This solves "Norvegian" problem and "Chinese" one, too.
Best regards,
Georgi Varbanov
|
|
|
|
| |
|
|
|
|
erikvanballegoij.com Joined: 4/7/2004
Posts: 4445
|
|
|
For dnn 3.2 we already worked on a better handling of locale selection, however this problem is still in the new code.
I think we need some kind of hybrid handling, as there are differences between for instance Internet Explorer and Firefox (firefox has 3 codes for norwegian: no, nb and nn. The latter 2 are wrong and should be nb-NO and nn-NO, which is correct in Internet Explorer).
I sent some new code to Vicenç for him to look at, which uses some of the suggestions given above. For instance a new function to get the correct language code from a localename:
Public Shared Function GetLanguageCode(ByVal localeName As String) As String 'create a cultureinfo object, and get the name of the parent, in order to get the generic language code Dim tempCI As CultureInfo Try tempCI = New CultureInfo(localeName) If tempCI.Parent.LCID <> 127 Then '127 = invariant culture ' try to get the parent CI first, only if the CI is not neutral already Return tempCI.Parent.Name Else 'take the ci.name if the ci is already neutral Return tempCI.Name End If Catch Return "en" End Try End Function
The returned code will be used to find out whether a locale is available and enabled
cheers,
erik
Erik van Ballegoij, Former DNN Corp. Employee and DNN Expert
DNN Blog | Twitter: @erikvb | LinkedIn:
|
|
|
|
| |