Tuesday, September 21, 2010

FirstWeekOfYear without getLocaleInfo

Sometimes it happens, that the function WinAPI::getLocaleInfo() raises an exception, when calling the Windows function GetLocaleInfoW in Kernel32.

While the function works for the GUI client, you get this exception in Enterpriseportal:
Dynamics Object Adapter Call failed.

Funktion 'GetLocaleInfoW' in DLL-Bibliothek 'KERNEL32' hat eine Ausnahmebedingung ausgelöst.

Microsoft.Dynamics.BusinessConnectorNet.XppException
at Microsoft.Dynamics.BusinessConnectorNet.AxaptaObject.Call(String methodName, Object[] paramList)
at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsObjectAdapter.Call(String methodName, Object param1)

The impact for the user was, that he just get a plain lookup popup window instead a calendar popup to select a date for a data field. *

I was unable to find the excact reason for that bug. But I assume it's the combination of x64 architecture, the .NET Business Connector and the use of a Unicode Windows Kernel function.

To bypass the error we've modified the method Global::firstWeekOfYear(), which was the caller to WinAPI::getLocaleInfo(), as follow:

Original:
static int firstWeekOfYear()
{
    #WinAPI
    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));
}
Modified:
static int firstWeekOfYear()
{
    /* #WinAPI
    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));
    */

    System.Globalization.DateTimeFormatInfo info = System.Globalization.DateTimeFormatInfo::get_CurrentInfo();
    System.Globalization.CalendarWeekRule rule = info.get_CalendarWeekRule();
    ;
    return(CLRInterop::getAnyTypeForObject(rule));
}

With this modification the Windows function GetLocaleInfoW in Kernel32 will not be direct used.

* Webframework based on Webforms (until AX 2009)

FirstWeekOfYear ohne getLocaleInfo

Manchmal kommt es vor, dass die Funktion WinAPI::getLocaleInfo() beim Aufruf der Windowsfunktion GetLocaleInfoW in Kernel32 einen Fehler verursacht.

Während die Funktion über den GUI-Client einwandfrei funktioniert, erhält man beim Aufruf über das Enterpriseportal eine Ausnahme:

Dynamics Object Adapter Call failed.

Funktion 'GetLocaleInfoW' in DLL-Bibliothek 'KERNEL32' hat eine Ausnahmebedingung ausgelöst.

Microsoft.Dynamics.BusinessConnectorNet.XppException
at Microsoft.Dynamics.BusinessConnectorNet.AxaptaObject.Call(String methodName, Object[] paramList)
at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsObjectAdapter.Call(String methodName, Object param1)

Für den Benutzer bedeutete dies, dass er in Lookupfenstern zum Auswählen eines Datums schlichtweg einfach nur eine weisse Seite sah, statt des erwarteten Kalenders.*

Leider konnten wir die Ursache des Fehlers nicht herausfinden. Ich vermute allerdings, dass die Kombination von x64-Architektur, dem .NET-Business-Connector und dem Aufruf einer Unicode-Windows-Kernelfunktion etwas damit zu tun hat.

Als Abhilfe haben wir die betreffende Methode Global::firstWeekOfYear(), welche in unserem Fall die Aufrufende Methode war, wie folgt angepasst:

Original:
static int firstWeekOfYear()
{
    #WinAPI
    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));
}
Modifiziert:
static int firstWeekOfYear()
{
    /* #WinAPI
    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));
    */

    System.Globalization.DateTimeFormatInfo info = System.Globalization.DateTimeFormatInfo::get_CurrentInfo();
    System.Globalization.CalendarWeekRule rule = info.get_CalendarWeekRule();
    ;
    return(CLRInterop::getAnyTypeForObject(rule));
}

Auf diese Weise wird die Windowsfunktion GetLocaleInfoW in Kernel32 erst gar nicht direkt verwendet.

* Webframework basierend auf Webforms (bis AX 2009)