I've got an MVC app that I've set the globalization in the web.config. All is well in the web app. But in my tests project I'm getting an issue in my service layer. I'm asking for date of birth in the following format dd/MM/yyyy. I'm passing this as a string to my service layer. I've got a RegEx to check that it is formatted correctly but when it is and I try to convert it to a date I'm getting an error. This is because the CultureInfo is set to en.US, I want it to be en.GB. I've tried in one of my initialise test methods to do the following, to no avail:
string sCulture = ConfigurationSettings.AppSettings["CultureToUse"]; //returns "en.GB"
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(sCulture);
CultureInfo.CreateSpecificCulture(sCulture);
Any ideas how to set CultureInfo in my tests project?
Since you enforce the format that the data is in and it only is numeric, you shouldn't rely on a user defined setting and are better off using DateTime.ParseExact(dateString, "dd/MM/yyyy", CultureInfo.InvariantCulture).
The CurrentUICulture property controls the resources that get loaded for the app. CurrentCulture is what you want to set/get to control parsing/formatting.
ConfigurationSettings.AppSettings["CultureToUse"]
Must return "en-GB" not "en.GB", hope this helps!
Related
I'm building one ASP.NET Core Web API and I've recently found one issue regarding the binding of DateTime values.
In truth I have one minimumDate and one maximumDate properties for filtering in a certain resource. These are part of one Filtering object which just gets populated on the controller by model binding.
The issue is that the request is sent like this:
minimumDate=2014-01-20T00:00:00.000Z&maximumDate=2014-03-21T00:00:00.000Z
and on the controller one gets when debuging:
MinimumDate = 19/01/2014 22:00:00
MaximumDate = 20/03/2014 21:00:00
This is clearly wrong. The expected was:
MinimumDate = 20/01/2014 00:00:00
MaximumDate = 21/03/2014 00:00:00
It is reducing one day in both the minimum and maximum dates and furthermore it is messing the time part.
I thought at first it had to do with culture and globalization, but this is already set in the Startup configure method as:
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-BR");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-BR");
so I doubt this to be the reason.
What am I doing wrong? How to get dates properly being sent to the API with model binding?
EDIT I managed to solve the issue by manualy parsing the datetime objects using:
filtering.MinimumDate = DateTime.Parse(this.Request.Query["minimumDate"], null, System.Globalization.DateTimeStyles.RoundtripKind);
filtering.MaximumDate = DateTime.Parse(this.Request.Query["maximumDate"], null, System.Globalization.DateTimeStyles.RoundtripKind);
In other words, bypassing the model binder. Still, I want to know: why model binding is presenting this strange behavior here?
To me it looks like the model binder which uses Json.net behind the scenes is converting your UTC time to local time for BRT (UTC-3) which is why you see the date and time change. You should be able to update your JsonSerializerSettings property as:
new JsonSerializerSettings
{
.....
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
.....
}
That should take care of proper model binding in your case.
I have an ASP .NET Web Forms application that makes use of the 'WebMethod' attribute for making AJAX calls from jQuery. I'm dealing with trying to localize the application so I recently created a web method that looks something like this for testing purposes:
[WebMethod]
public static string HandleDate(DateTime dateValue)
{
return dateValue.ToString("f");
}
The point of this method is to verify that if I set the CultureInfo properly the web method will parse the provided date correctly using the date formatting rules for that culture. Unfortunately, this code is never being reached. Instead, I'm seeing an error getting raised by the helper classes that allow these WebMethods to be called.
I have an HttpModule that is setting the 'CurrentCulture' and 'CurrentUICulture' properties of the current thread to 'pt-BR' (Brazilian Portuguese) at the 'BeginRequest' event.
Client side, I have a jQuery AJAX call to this 'HandleDate' web method that is providing the dateValue parameter as '18/10/2010'. In the 'pt-BR' culture this should evaluate to October 18, 2010 (day/month/year date format).
When I execute this I'm getting back an error indicating that the 'System.Web.Script.Serialization.ObjectConverter' is blowing up stating that '18/11/2010' is not a valid value for DateTime. The stack trace included with the error indicates that this was thrown by the 'System.ComponentModel.DateTimeCoverter.ConvertFrom' method, which accepts the object to be converted in addition to a CultureInfo object representing the culture that should be applied during the conversion.
I fired up Reflector and it appears that the 'ObjectConverter' is invoking the 'DateTimeConverter' using CultureInfo.InvariantCulture instance, which I think is the problem.
How can I force this logic to use the CultureInfo attached to the current thread instead of the InvariantCulture?
I would recommend you change the parameter type to string and then do the parsing yourself using DateTime.Parse or TryParse.
Another simple questions.
I have website with different languages. If I want to access a string from the resource file I would use it like this
Resources.MyResourceFile.MyStringIdentifier
Very easy. That way I know during compile time, that the resource string exists.
Now, this works only if I want to use the current Culture. Sometimes I need to specify a specific culture (let's say that the current user uses German as a language, but his action triggers messages to be sent to other users which will be in the recipient's language). Now, I see two options:
Resources.MyResourceFile.ResourceManager.GetString("MyStringIdentifier", neededCulturInfo)
The other would be to change the current thread's culture info which I would need to do several times.
Is there a third way? Something which tells me at compile time that the resources exist but without the need to change the thread's culture all the time?
(For your scenario) the idea of the ResourceManager is to provide culture specific informations at runtime not at compile time (aka side-by-side with fallback).
So the answer is "NO", there isn't a buildin way to determinate the existance of those resource files at compile time - to do so you would require a kind of "hard coding" for all strings in every single langauge and also code to access to those. The side by side idea is exactly the opposite of hardcoding ;)
What you could do, is writng a unit test for the resources, that itterates your langauges and checks if the default or a localized value was used. Further if you are using a source control system that provides check-in policies (e.g. TFS) you could this unit test as part of the check-in policy.
Have you tryied :
public static Object GetLocalResourceObject (
string virtualPath,
string resourceKey,
CultureInfo culture)
Try this link Click here
You can also try:
public static Object GetGlobalResourceObject (
string classKey,
string resourceKey,
CultureInfo culture)
Try this link Click here
ResourceSet has a method
public virtual IDictionaryEnumerator GetEnumerator()
that gives access to key-value pairs of the resource file.
E.g. (assuming we deal only with strings - N.B. the key-value pairs are of type object):
while (set.MoveNext())
{
string key = (string)set.Key;
// string value = (string)set.Value;
string value = ResourceManager.GetString(key, neededCulturInfo);
}
This is not what you should do, because things become complicated - just to point it out.
You could create different resource files for different cultures and use a switch code block in a method that has a CultureInfo as parameter.
You construct a class that looks inside the resource or use the Enumerator solution,look for the value and if it does not exist, make it use the value in the default language.
But in compile time, it cannot be verified.
The easiest option is a try-catch and return the value in the general language in the catch.
Nevertheless, if we are using resources, all the keys must always be present in all the related files, even if you copy them with the general language values.
My solution is what it should be, all the resources should be consistent, if not we are using this great tool badly.
The generated Resources.MyResourceFile class has a static Culture property, which you can set to neededCultureInfo to override the current thread's CurrentUICulture.
1) At the start maybe could be useful to store the UICulture into a session, in order to change it when you want, at the begin you can change it from there.
2) You can override the UICulture in preRender and set it from there and than storing it into session.
You can store it in a cookie as well but is not the best solution for it.
You can use WorkItems to send the messages asynchronously. Since you're now running on a different Thread, you should be able to modify the CurrentUICulture as needed.
P.S.: this is a good example why static dependencies are bad and everything should be interfaces & instances.
I am trying to achieve this but this is not working. I am sure i am missing something, please help me where i am wrong. I hope this is achievable. We should able to pass a string from ASP Page (using vbscript) to c# dll ( have this dll stored in gac and i have already registered it using regasm utility).
Below is my code:
Function GetObj()
Set Obj = Server.CreateObject("namespace.classname")
Set inputStr = Nothing
inputStr = "myString"
Set GetObj = Obj.dotnetMethod(inputStr)
SET Obj = NOTHING
End Function
The problem that i am facing is that when i passs inputStr to the obj.dotnetMethod, it is not recognising the string that i am passing from the asp page and it doesn't return to me any result which it should.
Could be a unicode problem--.Net expects unicode strings. ASP, I believe, does not.
But if you aren't even sure the method is registered, well then you have to make sure that dll is COM visible. ASP is a world that doesn't know anything about managed code or .Net. You have to use COM. You know, old school regsvr32, or ASP won't find it.
I can guess at a couple of things the might be going wrong (your question really needs more detail)
Set GetObj = Obj.dotnetMethod(inputStr)
dotnetMethod returns a String, DateTime or a primitive type such Int32 in which case you should remove the Set keyword.
dotnetMethod is return an object that isn't ComVisible itself.
BTW,
Set inputStr = Nothing
inputStr = "myString"
Why set inputStr to Nothing and then assign a string to it??
So I am working on a project which uses ASP.NET. I am trying to call Cache["key"] but the compiler complains about how System.Web.Caching.Cache is "nat valid at this point".
If I call Cache obj = new Cache(); the obj is always null.
I can access HttpContext.Current.Cache - but this doesnt let me specify an absolute expiration and sliding expiration in the Insert() method.
Can someone help me?
You should be able to absolute or sliding expiration calling the insert on HttpRuntime.Cache. It has several overloads. Ex:
HttpRuntime.Cache.Insert("EXAMPLE_KEY",
exampleItem,
Nothing,
DateTime.Now.AddHours(1),
System.Web.Caching.Cache.NoSlidingExpiration);
The exact same code should also work with HttpContext.Current.Cache.
I suggest you to try PCache class under PokeIn library. Even if you use FREE edition of that library, there is no limitation with this class. It has many more functionalities in comparison to ASP.NET Cache class and you dont have to deal with these problems. there is a simple sample project available on the web site.