Compartilhar via


Handling exceptions in code

You should write your code so that it can handle the system exceptions and validation exceptions that occur when you call methods from the Dynamics GP service. Typically, this means using a try/catch structure. In the try block, you place your code that calls the Dynamics GP service. The catch block handles the exceptions that might occur. This technique is used for both the legacy endpoint and the native endpoint, though the details of handling exceptions are different for the two endpoints.

Legacy endpoint

For the legacy endpoint, exceptions are returned as SoapException objects. Your code must reference the System.Web.Services.Protocols namespace so that this SoapException class is available.

When an exception occurs, your code has to determine whether it is a system exception or a validation exception. If the exception is a system exception, you can simply display the message included in the SoapException object. If the exception is a validation exception, you can retrieve and display the additional details about what was not valid.

One way to find out what type of exception occurred is to examine the InnerXml data of the Detail property for the SoapException object. If the InnerXml data has a <Message> node, then the exception is a validation exception. The <Message> node value is the GUID that is used to retrieve the validation exception details. If there is no <Message> node in the InnerXml data, the exception is a system exception.

The following C# example shows exception handling code for the legacy endpoint. The try/catch block traps and handles the SOAP exception. The code in the catch block determines the type of exception. If it is a system exception, the exception message is displayed. If it is a validation exception, the validation details are retrieved and displayed. Notice how the vendor object and the UpdateVendor method creates data that causes two validation exceptions.

Ff623150.LegacyEndpoint(en-us,MSDN.10).gif** Legacy endpoint**

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Web.Services.Protocols;
using System.Xml;
using DynamicsGPWebServiceSample.DynamicsGPService;

namespace DynamicsGPWebServiceSample
{
    class Program
    {
        static void Main(string[] args)
        {
            CompanyKey companyKey;
            Context context;
            VendorKey vendorKey;
            Vendor vendor;
            Policy policy;
            ValidationResult validationResult;

            // Create an instance of the service
            DynamicsGP wsDynamicsGP = new DynamicsGP();

            // Make sure that default credentials are being used
            wsDynamicsGP.UseDefaultCredentials = true;

            // Create a context with which to call the service
            context = new Context();

            // Specify which company to use (sample company)
            companyKey = new CompanyKey();
            companyKey.Id = (-1);

            // Set up the context
            context.OrganizationKey = (OrganizationKey)companyKey;

            // Create a vendor key of the vendor to be updated
            vendorKey = new VendorKey();
            vendorKey.Id = "ACETRAVE0001";

            // Create a vendor object
            vendor = new Vendor();
            vendor.Key = vendorKey;

            // Set a pair of properties to create two validation errors
            vendor.DiscountGracePeriod = 100;
            vendor.DueDateGracePeriod = 100;

            try
            {
                // Create a policy object
                policy = wsDynamicsGP.GetPolicyByOperation
                ("UpdateVendor", context);

                // Attempt to update the vendor
                wsDynamicsGP.UpdateVendor(vendor, context, policy);
            }
            catch (SoapException soapErr)
            {
                // Examine the InnerXml document to find whether the
                // /InnerException/Message node exists. If it does, then
                // this is a validation exception. If it does
                // not, then this is a system exception.

                // Try retrieving the Message node
                XmlDocument doc = new XmlDocument();
                XmlNamespaceManager nsManager = new
                    XmlNamespaceManager(doc.NameTable);
                nsManager.AddNamespace("sm",
            "http://schemas.datacontract.org/2004/07/System.ServiceModel");
                doc.LoadXml(soapErr.Detail.InnerXml);
                XmlNode node = doc.SelectSingleNode(
                    "//sm:InnerException//sm:Message", nsManager);
                if (node != null)
                {
                    // This is a validation exception

                    // Use the GUID retrieved to load the validation details
                    Guid LogId = new Guid(node.InnerText.Trim());

                    // Get the validation result object
                    validationResult = wsDynamicsGP.
                    GetLoggedValidationResultByKey(LogId, context);

                    // Display the validation exceptions
                    StringBuilder validationList = new StringBuilder();
                    foreach(ValidationError ve in validationResult.Errors)
                    {
                        validationList.AppendLine(ve.Message);
                    }
                    foreach(ValidationWarning vw in validationResult.Warnings)
                    {
                        validationList.AppendLine(vw.Message);
                    }

                    MessageBox.Show(validationList.ToString(), "Sample",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    // This is a system exception

                    // Display the message
                    MessageBox.Show(soapErr.Message, "Sample",
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
            }
        }
    }
}

Native endpoint

For the native endpoint, exceptions are returned as FaultException objects. Your code must reference the System.ServiceModel namespace so that this FaultException class is available.

When an exception occurs, your code has to determine whether it is a system exception or a validation exception. If the exception is a system exception, you can simply display the message included in the SoapException object. If the exception is a validation exception, you can retrieve and display the additional details about what was not valid.

One way to find out what type of exception occurred is to examine the Detail.InnerException property for the FaultException object. If this property is not null, then the exception is a validation exception. The property Detail.InnerException.Message will contain the GUID that can be used to retrieve the validation exception details. If the Detail.InnerException property for the FaultException object is null, the exception is a system exception.

The following C# example shows exception handling code for the native endpoint. The try/catch block traps and handles the service fault exception. The code in the catch block determines the type of exception. If it is a system exception, the exception message is displayed. If it is a validation exception, the validation details are retrieved and displayed. Notice how the vendor object and the UpdateVendor method creates data that causes two validation exceptions.

Ff623150.NativeEndpoint(en-us,MSDN.10).gif** Native endpoint **

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WebServiceSample.DynamicsGPService;
using System.ServiceModel;

namespace DynamicsGPWebServiceSample
{
    class Program
    {
        static void Main(string[] args)
        {
            CompanyKey companyKey;
            Context context;
            VendorKey vendorKey;
            Vendor vendor;
            Policy policy;
            ValidationResult validationResult;

            // Create an instance of the service
            DynamicsGPClient wsDynamicsGP = new DynamicsGPClient();

            // Create a context with which to call the service
            context = new Context();

            // Specify which company to use (sample company)
            companyKey = new CompanyKey();
            companyKey.Id = (-1);

            // Set up the context
            context.OrganizationKey = (OrganizationKey)companyKey;

            // Create a vendor key of the vendor to be updated
            vendorKey = new VendorKey();
            vendorKey.Id = "ACETRAVE0001";

            // Create a vendor object
            vendor = new Vendor();
            vendor.Key = vendorKey;

            // Set a pair of properties to create two validation errors
            vendor.DiscountGracePeriod = 100;
            vendor.DueDateGracePeriod = 100;

            try
            {
                // Create a policy object
                policy = wsDynamicsGP.GetPolicyByOperation
                ("UpdateVendor", context);

                // Attempt to update the vendor
                wsDynamicsGP.UpdateVendor(vendor, context, policy);
            }
            catch (FaultException<System.ServiceModel.ExceptionDetail> ex)
            {
                // Examine the InnerException property to find whether it
                // is null. If it is, then this is a system exception. If
                // it is not, then this is a validation exception.

                if (ex.Detail.InnerException != null)
                {
                    // This is a validation exception

                    // Retrieve the GUID to load the validation details
                    Guid LogId = new Guid(
                        ex.Detail.InnerException.Message.Trim());

                    // Get the validation result object
                    validationResult = wsDynamicsGP.
                    GetLoggedValidationResultByKey(LogId, context);

                    // Display the validation exceptions
                    StringBuilder validationList = new StringBuilder();
                    foreach (ValidationError ve in validationResult.Errors)
                    {
                        validationList.AppendLine(ve.Message);
                    }
                    foreach(ValidationWarning vw in validationResult.Warnings)
                    {
                        validationList.AppendLine(vw.Message);
                    }

                    MessageBox.Show(validationList.ToString(), "Sample",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    // This is a system exception

                    // Display the message
                    MessageBox.Show(ex.Message, "Sample",
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
            }
        }
    }
}