Utility_DotNet (Basic+)
At 30 DEC 2019 04:52:56PM Donald Bakke wrote:
We've been using the Utility_DotNet("TIMEZONE") service to return the current date/time in UTC format. It works very well. However, we have a site where calling this from the OEngineServer as a Windows Service is producing the following error:
Unable to invoke method Parse on class - Exception has been thrown by the target of an invocation. Exception: Exception has been thrown by the target of an invocation.þInner Exception: String was not recognized as a valid DateTime.Since this error is set via Set_Status(), it is causing our OECGI requests to fail and produce a 502 Bad Gateway response.
When we run the OEngineServer in debug mode this works just fine. We use the TIMEZONE service in many other sites without any issues. Any ideas as to what might be causing this to fail?
At 31 DEC 2019 07:57AM bshumsky wrote:
We've been using the Utility_DotNet("TIMEZONE") service to return the current date/time in UTC format. It works very well. However, we have a site where calling this from the OEngineServer as a Windows Service is producing the following error:
Unable to invoke method Parse on class - Exception has been thrown by the target of an invocation. Exception: Exception has been thrown by the target of an invocation.þInner Exception: String was not recognized as a valid DateTime.Since this error is set via Set_Status(), it is causing our OECGI requests to fail and produce a 502 Bad Gateway response.
When we run the OEngineServer in debug mode this works just fine. We use the TIMEZONE service in many other sites without any issues. Any ideas as to what might be causing this to fail?
Hi, Don. When you're testing this in 'debug' mode, you aren't running as the same user as when you're running as a service (I assume). This means that if there are environmental settings that control how the date/time should be converted, they may be different for the 'services' user versus the 'desktop' user.
1. Could you call SET_STATUS(0) after the timezone call, just to 'clear up' any pending statuses? That might at least get you past the Bad Gateway error;
2. What, exactly, are you passing in to the Utility_DotNet call? Is it just "TIMEZONE", or is there a specific date you're passing in, and/or a specific timezone? Are you passing in the "this is already in output format" flag?
3. If you're not passing in a specific date/time, and you're not passing in the "already in output format" flag, the code does something like this:
If inDate = "" Then inDate = RTI_DATETIME() outDate = Oconv(inDate, "DT^S")I would suggest putting this same code into YOUR routine, and writing the information out somewhere before your Utility_DotNet call. Then you can compare the call that works with the call that doesn't work - is your "outDate" correct in both cases?
4. Once the date/time is generated in output format, it's passed to the .Net System.DateTime object, which has to parse it. This object uses the 'current culture" (previously known as "locale") to determine what's a valid date/time format. Although unlikely, maybe it's possible that the locale is somehow different when run as the services user versus the desktop user?
I'd start by taking a look at these things, and see if any of them help you to resolve (or at least track down) the problem.
Hope that helps,
- Bryan Shumsky
At 31 DEC 2019 09:26AM Donald Bakke wrote:
When you're testing this in 'debug' mode, you aren't running as the same user as when you're running as a service (I assume). This means that if there are environmental settings that control how the date/time should be converted, they may be different for the 'services' user versus the 'desktop' user.
Correct, the service is using the SYSTEM user. In "debug" mode it's using my user.
Could you call SET_STATUS(0) after the timezone call, just to 'clear up' any pending statuses? That might at least get you past the Bad Gateway error;
Yes. After I finally traced the problem to this line of code, I started to clear the error to avoid the Bad Gateway error.
What, exactly, are you passing in to the Utility_DotNet call? Is it just "TIMEZONE", or is there a specific date you're passing in, and/or a specific timezone? Are you passing in the "this is already in output format" flag?
The actual code I'm calling is this:
DateTime = Utility_DotNet('TIMEZONE', '', -1)If you're not passing in a specific date/time, and you're not passing in the "already in output format" flag, the code does something like this:
If inDate = "" Then inDate = RTI_DATETIME()
outDate = Oconv(inDate, "DT^S")
I would suggest putting this same code into YOUR routine, and writing the information out somewhere before your Utility_DotNet call. Then you can compare the call that works with the call that doesn't work - is your "outDate" correct in both cases?
I'm not sure what you are after so I'll just share what happens in all instances. If I call the code you provided it returns the following:
01 JAN 2020 00:12:05
When I use Utility_DotNet it returns the following:
Tue, 31 Dec 2019 14:12:05 GMT
So they are the same date/time, but one is UTC formatted and the other is local time. Also, as you might infer from the local time, this is an Australian site.
Once the date/time is generated in output format, it's passed to the .Net System.DateTime object, which has to parse it. This object uses the 'current culture" (previously known as "locale") to determine what's a valid date/time format. Although unlikely, maybe it's possible that the locale is somehow different when run as the services user versus the desktop user?Sounds plausible. Not sure how to prove that.
At 31 DEC 2019 09:45AM bshumsky wrote:
The actual code I'm calling is this:
DateTime = Utility_DotNet('TIMEZONE', '', -1)<snip>
I'm not sure what you are after so I'll just share what happens in all instances. If I call the code you provided it returns the following:
01 JAN 2020 00:12:05
When I use Utility_DotNet it returns the following:
Tue, 31 Dec 2019 14:12:05 GMT
So they are the same date/time, but one is UTC formatted and the other is local time. Also, as you might infer from the local time, this is an Australian site.
OK, thanks.
What I was suggesting was putting this code:
If inDate = "" Then inDate = RTI_DATETIME() outDate = Oconv(inDate, "DT^S")and writing out the results, into your stored procedure just before the UTILITY_DOTNET call. Then, run your stored procedure as the service user and see what's written out; next, run your stored procedure in 'debug' mode and see what's written out THEN. Are they the same values, or different?
Knowing that this is a non-US locale convinces me further that the problem is likely that, when run as the service user, we're generating a date that's in US format but the .Net assembly is trying to understand it as an Australian date, or vice versa.
Thanks,
- Bryan Shumsky
At 31 DEC 2019 09:51AM Donald Bakke wrote:
I understand you better. Fortunately, I did do exactly that and the code sample you provided me returns the same value whether I run it in Service mode or Debug mode.
At 31 DEC 2019 01:37PM bshumsky wrote:
I understand you better. Fortunately, I did do exactly that and the code sample you provided me returns the same value whether I run it in Service mode or Debug mode.
OK, if we're providing the same output format of date, and yet you're generating an error when it's running as the service user, I can only guess that the locale for the Service user is set differently than for the logged-in user when run in debug mode.
You might try generating the date yourself, in output format that's perhaps "less confusing" for the Australia locale, and passing that in directly (rather than letting the UTILITY_DOTNET make the date for you). So your call could be something like this:
currDateTime = RTI_DATETIME() ;* get the current datetime value outDateTime = oconv(currDateTime, "DTJ-^S") ;* generate the date in ISO-8601 format RSLT = UTILITY_DOTNET("LOCALE",outDateTime, "-1", "1")I believe that by using the ISO-8601 format (YYYY-MM-DD), you should get a date that works with most (all?) locales…
Hope that helps,
- Bryan Shumsky