As a developer of an HttpModule that is used in over 150 countries, I want to make sure I'm doing the right thing by making all web.config data culture-invariant. This means any date/time values, floating-point, or integers specified in Web.config should be parsed with the invariant culture (generic english).
Is this the correct convention to follow? Extensive googling didn't turn up an answer.
I recommend that you use the invariant culture for all configuration settings in Web.config, because that is the convention followed by ASP.NET. Your users will probably find it confusing to have to specify invariant data in certain places and localized data in other places.
(ASP.NET relies on the functionality in System.Configuration to parse configuration data. The internal ConfigurationProperty.ConvertFromString method calls TypeConverter.ConvertFromInvariantString to convert a string to a typed value. You too can use System.Configuration; see the MSDN Library documentation.)
I am not sure that there even is a convention for this. Come to think of it I'm not sure what I would expect. I would probably be surprised if the module didn't behave as expected because a setting was parsed in an unexpected culture.
But let's say for the sake of argument you want to do follow a different convention (not invariant by default). I think it would be most logical to read the <globalization> settings and use the culture setting (not the uiCulture because that is for loading resources).
This way it is configurable for your customers. Of course you need to take care to use an IFormatProvider based on the culture setting to parse the settings:
string setting = ConfigurationManager.AppSettings["size"];
IFormatProvider format = CultureInfo.GetCultureInfo(configSection.Culture).NumberFormat;
float size = float.Parse(setting, format);
I'd say it would be good to cache the configuration setting in HttpContext.Application the first time it's read. If web.config changes the app domain will be reloaded anyway.
A possible downside is that when you want to document your library you will have to educate users that they can't just copy-paste configuration values since their environment may have a different culture setting and thus they may encounter errors that could be hard to understand.
PS. Looking at the configuration documentation for your module, I noticed the <cleanupStrategy> element. That looks unusual to me. I would expect to specify its values in seconds or some other integer value, like <sessionState timeout="number of minutes">.
Related
I wonder if any of you got a suggestion on how to easy change different setup when using different ConnectionStrings (and possibly other settings too). Currently, when debugging with different ConnectionStrings, I uncomment/comment the one I want to use/don't want to use.
Is there a way to group a collection of settings and use a single value to determine which settings to use?
I don't meen the possibility to have a nested web.config, as Release.web.config and a Debug.web.config, because I HAVE TO use the Debug configuration.
Your application could have a single class responsible for handing out connection string values. Given a parameter it would pull the appropriate string from the .config files.
IMO you should be doing this anyway in case you change the connection string name - if you encapsulate what can change within a class the app is easier to manage.
I don't think you can add some conditional logic directly to the .config files to do this for you.
I have been trying to get culture specific resources to work on an asp.net mvc 3 application.
If I have a LanguageResources.resx and a LanguageResources.en-UK.resx in my App_GlobalResources folder then I get an error "The namespace 'Resources' already contains a definition for 'LanguageResources'"
This is the end of a long line of issues that I have had with trying to get culture specific resources to work. I must say, I'm not impressed with the documentation Microsoft provide for using this feature.
I'm considering using a database table to store my culture specific strings instead, then I can just build a dictionary of all the values that will be available to my controller and views.
Has anyone else made such a decision, or have any direct knowledge on performance issues related to using a database for culture specific strings?
Has anyone else given up on resources too?
I must admit, I tried to reproduce your defect and I was successful. It looks like, Visual Studio generates additional class when you add something.en-UK.resx. Strange. It should not allow you to add anything like this in the first place for there is no such culture.
How to resolve the problem? Just add LanguageResources.en-GB.resx and delete
LanguageResources.en-GB.resx. That helps.
I would not use database for storing language-related resources, unless they are changing very frequently or must be entered by end users (i.e. there are some kind of templates).
Using the database hurts Localizability and requires much effort. It is hard to design correctly (I have seen a lot of mistakes in that area). Don't go that road unless you really have to.
what is the result of setting the current thread's culture code?
I understand if I use the resource file it will pull label's/strings from the .resx file.
What else? Will it effect my date/money formatting also?
Setting Thread.CurrentCulture will affect formatting and parsing of dates and numbers. Setting Thread.CurrentUICulture affects fetching resources from resource files.
yes, your Date, money and other setting will be according to your thread 's culture.
When you set thread's culture, your application run under that culture.
It MIGHT affect date and money formatting, depending on how you do the formatting. I think the default ToString() will usually check the treads UI culture, but if you have any custom formatting it will override the defaults.
See http://msdn.microsoft.com/en-us/goglobal/bb896001 National Language Support codes in various operative systems
I could definitely accomplish what I want with a custom handler, but I was hoping it would be possible to adjust the web.config to define allowable cultures. Basically, I have a website that has resource files for a number of languages. I would like to deploy the same website to different domains with different configurations specifying the default cultures. I know I can set a specific culture to be used in the web.config, but can I also specify multiple cultures?
Even though I have English language resource files, I don't want a visitor from the US to certain domains to see the English version, but I can't fix the site for a single culture, either.
It sounds like you are asking three different questions:
Can you filter for the cultures used?
Yes. Create a base class for all your pages where you override the Page.InitializeCulture method and only allow certian cultures to be used.
Can you do it in web.config?
No. The best you can do in the web.config file is indicate a single culture.
Can you limit users from certain geographical places on the net?
This is a tougher question. First, you will never have perfect filtering as the Internet makes this pretty much impossible. However, you can get close by geo-locating based on IP. See Geolocation for more. There are a number of services on the net that will provide this functionality for you.
I have an application that is multilingual. I'm using the out-of-the-box .Net features for this. Each language has its own file in the App_GlobalResources (see iamge below)
In the code behind what is better?
GetGlobalResourceObject("LocalizedText", "ErrorOccured")
Resources.LocalizedText.ErrorOccured
The 2nd one uses less code and it's type safe, it will return an error during compile time and not run time.
alt text http://img340.imageshack.us/img340/5562/langl.gif
These are the advantages of each approach:
Advantages of GetGlobalResourceObject (and GetLocalResourceObject):
You can specify a particular culture instead of using the CurrentCulture.
You can use a late-bound expression (i.e. a string) to decide which resource to load. This is useful if you can't know ahead of time which resource you will need to load.
It works with any resource provider type. For example, it works not only with the built-in default RESX-based provider but it'll work the same against a database-based provider.
Advantages of strongly-typed RESX types:
You get compile-time errors if you access a resource that doesn't exist.
You get Intellisense while working on the project.
So, as with many "which is best" questions, the answer is: It depends! Choose the one that has advantages that will benefit your particular scenarios the most.
So use the second one, if you know up-front what the resource file and key will be.
The GetGlobalResourceObject() method is useful if you don't know what the resource file or (more likely) the key will be at compile time.