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
Related
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">.
I have two different contexts on a Plone instance.
The first context has some ATFolders. The second, have ATFolders too that have to be in sync with the first context using some subscribers.
In the second context, the ATFolders have to know that they are linked to some of the folders on the first context.
I thought about using setattr in them (setattr(obj_context1, attr, obj_context2.UID())) instead of creating a new Content-Type just to have a ReferenceField attribute (or using archetype.schemaextender), since this would be too much overkill for just a single parameter in a specific context: the folders that will have this attribute will not be deleted from ZODB for example. They will have a placeful workflow with just one state. This attribute is completely hidden from the user, and the folders on the second context are programatically created, with no user intervention.
This attribute should only exist in the second context, so creating an adapter or a new content-type, just to be used in this context seems to be too much.
I'm inclined to use setattr for the sake of pragmatism on this specific scenario, but I don't know if using the setattr approach is going to haunt me in the future (performance, zodb conflicts, etc). I mean: doing an update catalog, update workflow, is this new attribute going to have a problem?
Any thoughts? Anyone experienced with setattr in this situation? This attr will and should not be visible, it's only for some control.
I don't think it's bad practice at all, I do similar things for similar situations.
You could use an attribute annotation, which would help prevent conflicts with other attributes, but that's a style and performance choice more than anything. Attribute annotations are stored in their own ZODB persistent record, so it depends on how often this attribute will change compared to the other attributes on the folder what impact this has.
Last but not least, I would probably encapsulate the behaviour in an adapter, to make the implementation flexible for future uses. You can either register the adapter to the ATFolder interface, or to IAttributeAnnotatable, depending on how much your implementation relies on what the adapted object needs to provide.
Other notes: We've also used plone.app.relations connections between objects in the past (maintained outside the object schema, like your attribute), but found five.intid (the underlying machinery .relations relies on) to be too fragile and would use simple UID attributes with catalog searches in the future.
In reference to Ross's answer, if the information in question doesn't need to be end-user editable, a schemaextender attribute is overkill.
Maybe use archetypes.schemaextender? See also this doc. This way you can use an actual ReferenceField, get all sorts of stuff for free, and spend a lot less time re-implementing said free stuff.
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.
Are there any advantages of using one over the other besides readability?
Nope, they do the same thing. Session["item"] is the same as Session.Item["item"].
You will be accessing the same collection with either.
Its just a hang over from classic ASP, where the session object is implement as a COM object. COM could nominate one property as the default property (which typically would take an indexing parameter). In the case of Session the Item property is the default property.
In an effort to allow classic ASPers to port code to .NET the Session, Server, Request, Response and Application classes were crafted to be similar between classic and .NET ASP.
Personally, I think referencing a property explicitly (Session.Item("Hello")) is always more readable than relying on that property's being the default (Session("Item")), but the readability is at the expense of more typing. If typing is a problem for you, switch to Ruby-on-Rails.