Thursday, February 16, 2017

Web Client: HTTP Error 500.0 - Internal Server Error

Just recently I was assisting a partner on the Dynamics GP Partner forum with an error they were receiving when attempting to log into the Microsoft Dynamics GP web client.

Summary

The partner reported they could log into web client just fine from the SQL Server. However, when they launched web client from the Web Server that host the Dynamics GP web application, they received:

HTTP Error 500.0 - Internal Server Error



Now, this error is a pretty generic error. In addition to not being able to log in, the landing page would not display the Microsoft Dynamics GP logo.

Troubleshooting the Issue

The partner had tried the following troubleshooting techniques:
  1. Repaired Microsoft Dynamics GP web components
  2. Uninstalled and reinstalled web components
  3. Rebooted the server
In addition, I recommended my article Microsoft Dynamics GP 2016 web client UI not displaying icons to ensure static content had been enabled during Internet Information Services (IIS) configuration. Typically, when static content is not enabled, the web client image resources do not get displayed.

Usually, after trying options 1 and 2, if you are still experiencing issues not allowing you to bypass the login window, you know you are facing a pre-requisite configuration issue.

Reading the Detailed Error Information section, you will notice that the error was caused by an authentication request, trying to access an image resource file using Anonymous Authentication by an Anonymous user. In simple terms, this is a permissions issue.

Upon inspecting the GP website authentication setting, the partner noticed the credentials for the anonymous user identity were set to IUSR.



So what's the big deal?

Anonymous authentication gives users access to the public areas of your website without prompting them for a user name or password. When a user attempts to connect to your public Web site, your Web server assigns the user to the Windows user account called IUSR.

By default, the IUSR account is included in the IIS_USRS built-in group. This group has security restrictions, imposed by NTFS permissions that designate the level of access and the type of content available to public users. With that said, websites such as the GP web belong in the private domain and most organizations disable anonymous authentication totally for the GP websites and revoke access to the IUSR account or IIS_USRS group to the website folder to prevent unauthorized access.

If you are running IIS 7.5 on Windows Server 2008 R2, or a later version of IIS, for every application pool you create, the Identity property of the new application pool is set to ApplicationPoolIdentity by default. The IIS Admin Process (WAS) will create a virtual account with the name of the new application pool and run the application pool's worker processes under this account by default.

By setting the ApplicationPoolIdentity as the anonymous user account for a site, you can isolate content and configuration for that site so that no other sites on the same IIS web server can access it, even if you have enabled anonymous authentication. GP web client installation allows you to specify a domain account as the identity for the Web Management Console and GP web application pools. The installer in turn will ensure the proper permissions are given to the folders hosting the web site and the GP web components.

This is particularly useful if you are a hosting provider running multiple customer websites on a single IIS server. Having the ability to control the website access and the content that is displayed is very important.

For a primer on IUSR vs application pool identity, take a look at the following article by Tristan K.

IUSR vs Application Pool Identity – Why use either?

The fix

In this particular case, switching the Anonymous Authentication credentials from IUSR to ApplicationPoolIdentity fixed the issue, although, keep in mind that the GP web client does not require anonymous authentication to be enabled.

Until next post!

MG.-
Mariano Gomez, MVP

Wednesday, February 15, 2017

VST: An error occurred while loading or initializing an addin

As I mentioned before, I am now the Lead Software Engineer at Mekorma. I love it here as I get to work with some really talented software engineers and developers, all of which challenge me everyday. One of the cool new products we are working on, Mekorma Multi-Batch Management, allows you to build payment batches, print and post payments, and generate electronic funds transfer (EFT) and positive pay (Safe Pay) files, across companies, and across multiple checkbooks, with some minor configuration and just the click of a button. You can see an in-depth video on the product here.


Part of the challenges of building Multi-Batch Management were its extensive interfacing with both our own Mekorma MICR product and Microsoft Dynamics GP, and in particular, the Safe Pay module - Multi-Batch Management is designed to drive the Microsoft Dynamics GP user interface, thus eliminating the need for invasive code.

If you have worked on integrating code for Microsoft Dynamics GP, you are certainly familiar with the challenges surrounding the response to Dexterity modal dialogs. This is true for Microsoft Dexterity service enabled procedures as much as it is true for standard applications like ours, that simply try to drive the user interface.

NOTE: Dexterity does not have a programmatic mechanism to respond to modal dialogs. As it stands, only Visual Basic for Applications (VBA) and Visual Studio Tools for Microsoft Dynamics GP (VST) provide event handlers for modal dialogs.

VST aids in responding to Dexterity modal dialogs by allowing a developer to define form or window level modal event handlers. Because our code needed to respond to dialogs in Safe Pay only when our process was running, it was necessary to create an application assembly for our dictionary, that we could then reference in a Visual Studio Tools project. In addition, we needed to reference the Safe Pay application assembly as well. The project reference looks something like this:


Project References

Once references are added to the project, the tendency is to immediately add all event handlers to the Initialize() method within the GPAddIn class, as shown below:


public void Initialize()
{
   Dynamics.Forms.SyErrorMessage.SyErrorMessage.OpenBeforeOriginal += 
     Dynamics_SyErrorMessage_OpenBeforeOriginal;
   Dynamics.Forms.CmTransactionEntry.CmTransactionEntry.BeforeModalDialog += 
     Dynamics_BeforeModalDialog;
   Dynamics.Forms.CmEftGenerateFiles.CmEftGenerateFiles.BeforeModalDialog += 
     Dynamics_BeforeModalDialog;
   SafePay.Forms.MePpTransactions.MePpTransactions.BeforeModalDialog += 
     new EventHandler(SafePay_Transactions_BeforeModalDialog);
}


Unfortunately, this approach has a problem: let's assume Safe Pay is not installed, therefore, the Safe Pay application dictionary and application assembly are missing from the Dynamics GP installation folder. Since the Initialize() method is the entry point to your VST application, when the runtime engine attempts to load your assembly, your application would contain a reference to a non-existing assembly. This in turn will cause the runtime engine to produce the following error:

"An error occurred while loading or initializing an addin. As your administrator to check the Windows event log for more details. Dynamics will now close."


This is always been accepted as "the way things work". Unfortunately, we couldn't live with the status quo as it meant that customers who did not require the Safe Pay module would have to install it just for the sake of our assembly not failing.

We then attempted to move our event handler registration into it's own method, enveloping the call in a try..catch block:


public void Initialize()
{
   Dynamics.Forms.SyErrorMessage.SyErrorMessage.OpenBeforeOriginal += 
     Dynamics_SyErrorMessage_OpenBeforeOriginal;
   Dynamics.Forms.CmTransactionEntry.CmTransactionEntry.BeforeModalDialog += 
     Dynamics_BeforeModalDialog;
   Dynamics.Forms.CmEftGenerateFiles.CmEftGenerateFiles.BeforeModalDialog += 
     Dynamics_BeforeModalDialog;

   try 
   {
     InitializeSafePay();
   }
   catch (Exception e) 
   {
     throw new Exception(e.Message);
   }
} 

public void InitializeSafePay()
{
  SafePay.Forms.MePpTransactions.MePpTransactions.BeforeModalDialog += 
    new EventHandler(SafePay_Transactions_BeforeModalDialog);
}


The above produced virtually the same results. That is, the exception was still being displayed. Now, quite clearly, if we commented out the throw statement, the exception would no longer present itself and the message would not appear, precisely what we needed since we did not want to alert of the missing assembly and prevent the user from login into Dynamics GP.

NOTE: Alternatively, we implemented tracing capabilities for our assembly, so now all exceptions are recorded in a log file.

Special thanks to my Sr. Software Engineer, Lee Butenhoff for researching and providing a solution to this long standing issue.

Until next post!

MG.-
Mariano Gomez, MVP

Tuesday, February 14, 2017

Revisiting: SOP Quick Print

Continuing with my Revisiting series, today I look at an article I wrote in 2009 regarding the SOP Quick Print feature.

Summary

SOP Quick Print is one of those gems in Microsoft Dynamics GP hidden within plain site. Written by my friend David Musgrave, it was designed to save time when saving and printing sales orders, fulfillment orders, and invoice. SOP Quick Print is activated by pressing CTRL + Q on your keyboard, and after a simple setup, it's good to go.

SOP Quick Print Setup window
One of the frustrating things about saving most documents in Dynamics GP, is that the window is cleared completely from the document that you were working on. Depending on what you are trying to achieve, this can be an inconvenience if all you wanted to do is save your document up to that point, so you can keep working on it. Current business logic would have you retrieving that document once more by either typing the document number or retrieving it via a lookup. With SOP Quick Print, you can save the document while keeping it displayed on the Sales Transaction Entry window.

SOP Quick Print and the Web Client

In order to achieve the printing and the saving of the document, SOP Quick Print creates a Dynamics GP macro on the fly, with the necessary macro lines (based on the selected options during configuration) to print, save, and retrieve the document when saved. The macro looks something like this:

ActivateWindow dictionary 'default'  form 'SOP_Print_Options' window 'SOP_Print_Options'
  MoveTo field 'Print Button NONE'
  ClickHit field 'Print Button NONE'
NewActiveWin dictionary 'default'  form 'Report_Destination' window 'Report_Destination'
  MoveTo field 'Print to Screen'
  ClickHit field 'Print to Screen'
  MoveTo field 'OK Button'
  ClickHit field 'OK Button'
PrintDialog copies 0 from 0 to 0


The macro is saved in the Data folder of the current instance.

The issue with macros is, they are not compatible with the Dynamics GP web client, so unfortunately, this great feature is not available when running the web client. But if you currently enjoy the desktop client, there should be absolutely no reason for you not to take advantage of this feature.

I have tested this across all newer versions of Dynamics GP, since GP 2013 and the feature continues to work as expected.

Until next post!

MG.-
Mariano Gomez, MVP

Monday, February 13, 2017

You receive "Unhandled Script Exception: Invalid Product ID 258" when attempting drill-down into an invoice from Purchasing All-In-One view

Just recently, I was helping someone on a forum with a question regarding the Purchasing All-In-One view. The consultant could not get the view to show the receipts and invoices for some vendor POs. In order to assist with the issue, I had to try and recreate the issue myself. Needless to say, I could not recreate the specific problem reported by the consultant. However, in an attempt to drill-down on a specific invoice voucher, I received the following error message:

Unhandled script exception:
Invalid Product ID 258.

EXCEPTION_CLASS_SCRIPT_OUT_OF_RANGE
SCRIPT_CMD_CALL




Product 258 corresponds to Project Accounting. Suffice to say, there isn't any validation in place to determine if the Project Accounting dictionary is present, before attempting to display the invoice. The workaround, of course, is to install Project Accounting even if you don't need it, until a fix is in place from Microsoft.

This issue is present in Microsoft Dynamics GP 2015 R2 YE (14.00.1016) and Microsoft Dynamics GP 2016 RTM (16.00.0404). I have not tested GP 2016 R2, but see no specific reason to believe this is been fixed, given the fact that this condition only occurs if Project Accounting is not installed.


Until next post!

MG.-
Mariano Gomez, MVP