Creating a Custom Serialization Assembly for eConnect for Microsoft Dynamics GP 2010

Chris Roehrich - Click for blog homepageThe eConnect Programmer's guide discusses creating a custom XML node and stored procedure so developers can process new types of data.   For example, a custom or 3rd party table could be updated when integrating a master record like a Customer or a transaction like a Sales Invoice using eConnect.   The strategy that I will discuss below is for developers out there that would like to go one step further by referencing their own custom assembly.  This assembly can be referenced in their Visual Studio project which would allow them to serialize the eConnect XML document with the custom node.  

In the "Custom XML Nodes" section of the eConnect Programmers guide, the custom stored procedure is named eConnectCustomProcedure.  It has one input parameter named CUSTNMBR that holds a Customer ID value.  The custom XML node would look like this:

    <eConnectCustomProcedure>
      <CUSTNMBR>AARONFIT0001</CUSTNMBR>
    </eConnectCustomProcedure>

To use your custom XML node you will need to include this in a eConnect XML document like the following: 

<eConnect xmlns:dt="urn:schemas-microsoft-com:datatypes">
    <RMCustomerMasterType>
        <eConnectProcessInfo>
            <eConnectProcsRunFirst>TRUE</eConnectProcsRunFirst>
        </eConnectProcessInfo>
        <eConnectCustomProcedure>
            <CUSTNMBR>CONTOSOL0002</CUSTNMBR>
        </eConnectCustomProcedure>
        <taUpdateCreateCustomerRcd>
            <CUSTNMBR>CONTOSOL0002</CUSTNMBR>
            <CUSTNAME>Contoso, Ltd.</CUSTNAME>
            <TAXSCHID>USALLEXMPT-0</TAXSCHID>
            <ADRSCODE>PRIMARY</ADRSCODE>
            <ADDRESS1>321 Main S </ADDRESS1>
            <CITY>Valley City</CITY>
            <STATE>ND</STATE>
            <ZIPCODE>56789</ZIPCODE>
            <COUNTRY>USA</COUNTRY>
            <PHNUMBR1>13215550100</PHNUMBR1>
            <PHNUMBR2>13215550110</PHNUMBR2>
            <FAX>13215550120</FAX>           
        </taUpdateCreateCustomerRcd>
    </RMCustomerMasterType>
</eConnect>

The question is how can we serialize a document like this in our Visual Studio project when the existing eConnect serialization assembly does not know anything about the custom node?  The answer is we will create a new assembly that we can reference in the Visual Studio project.   This approach allows the developer to follow the pattern of working with the types in the serialization assembly like we provide in the eConnect documentation and SDK samples.

The first step I did was edit the RMCustomerMaster.xsd file located under the C:\Program Files (x86)\Microsoft Dynamics\eConnect 11.0\XML Sample Documents\Incoming XSD Individual Schemas folder. I used Visual Studio 2010 for this step over Notepad since it is easier to read. I added a new element called eConnectCustomProcedure for the RMCustomerMasterType complex type like below:

 <xs:complexType name="RMCustomerMasterType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="eConnectProcessInfo" nillable="true" type="eConnectProcessInfo" />
      <xs:element minOccurs="0" maxOccurs="1" name="taRequesterTrxDisabler_Items" nillable="true" type="taRequesterTrxDisabler_Items" />
      <xs:element minOccurs="0" maxOccurs="1" name="taUpdateCreateCustomerRcd" nillable="true" type="taUpdateCreateCustomerRcd" />
      <xs:element minOccurs="0" maxOccurs="1" name="taCreateCustomerAddress_Items" nillable="true" type="taCreateCustomerAddress_Items" />
      <xs:element minOccurs="0" maxOccurs="1" name="taCreateInternetAddresses_Items" nillable="true" type="taCreateInternetAddresses_Items" />
      <xs:element minOccurs="0" maxOccurs="1" name="taCreateParentID" nillable="true" type="taCreateParentID" />
      <xs:element minOccurs="0" maxOccurs="1" name="taParentIDChild_Items" nillable="true" type="taParentIDChild_Items" />
      <xs:element minOccurs="0" maxOccurs="1" name="eConnectCustomProcedure" nillable="true" type="eConnectCustomProcedure" />
    </xs:sequence>
  </xs:complexType>

I then added a new complex type near the bottom of the file right above the </ xs:schema> end tag. I used the below string type for the CUSTNMBR parameter that the custom procedure needs like below:

 <xs:complexType name="eConnectCustomProcedure">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="CUSTNMBR" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Next I used the xsd.exe tool to build a new class based on the XSD file. I used the below syntax at a command prompt in the C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC directory. This is the Microsoft Visual Studio Command Prompt for Visual Studio 2010 that is available in the Microsoft Visual Studio 2010 program folder.

xsd "C:\eConnectDev\RMCustomerMaster.xsd" /c

This step creates a class file named RMCustomerMaster.cs in the C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC folder. I added the new class file to a Visual Studio 2010 C# library project named RMCustomerCustomECONNECT that used a default namespace of RMCustomerCustomECONNECT. You could modify the code in the class file to add your own custom namespace but I left it alone using just the default from Visual Studio 2010. After building the project in Visual Studio 2010 it created an assembly named RMCustomerCustomECONNECT.dll.

Lastly, I made a reference to this new assembly and the Microsoft.Dynamics.GP.eConnect.dll assembly in my eConnect project. This is a C# Console Application that serializes the XML document with the custom node and passes it to the CreateEntity method of the eConnectMethods class. The code looks like the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Dynamics.GP.eConnect;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace CreateCustomerWithECONNECTCustomXML
{
class Program
{
static void Main(string[] args)
{
using (eConnectMethods eConCall = new eConnectMethods())
{
try
{
// Create the eConnect document and store it in a file
SerializeCustomerObject("customer.xml");

// Load the eConnect XML document from the file into
// an XML document object
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("customer.xml");

// Create an XML string from the document object
string customerDocument = xmldoc.OuterXml;

// Create a connection string
//Integrated Security is required. Integrated security=SSPI
string sConnectionString = "data source=croehric1\\sqlexpress;initial catalog=TWO;integrated security=SSPI;persist security info=False;packet size=4096";

// Use the eConnect_EntryPoint method to create the sales document in Microsoft Dynamics GP
// The XML string is not validated by the method call
eConCall.CreateEntity(sConnectionString, customerDocument);
}
// The eConnectException class will catch any business logic related errors from eConnect_EntryPoint.
catch (eConnectException exp)
{
Console.Write(exp.ToString());
}
// Catch any system error that might occur. Display the error to the user
catch (Exception ex)
{
Console.Write(ex.ToString());
}
Console.WriteLine("-----");
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}

}

private static void SerializeCustomerObject(string filename)
{
try
{

RMCustomerMasterType rmCustomerMasterType = new RMCustomerMasterType();
eConnectProcessInfo procInfo = new eConnectProcessInfo();
taUpdateCreateCustomerRcd customerRecord = new taUpdateCreateCustomerRcd();
eConnectCustomProcedure customProcNode = new eConnectCustomProcedure();

customerRecord.CUSTNMBR = "AARONFIT0001";
customerRecord.UpdateIfExists = 1;

customProcNode.CUSTNMBR = customerRecord.CUSTNMBR;

rmCustomerMasterType.taUpdateCreateCustomerRcd = customerRecord;
rmCustomerMasterType.eConnectCustomProcedure = customProcNode;
procInfo.ProductName = "eConnect Test";
rmCustomerMasterType.eConnectProcessInfo = procInfo;

eConnectType eConnect = new eConnectType();
RMCustomerMasterType[] MyCustomerTransactionType = { rmCustomerMasterType };
eConnect.RMCustomerMasterType = MyCustomerTransactionType;

// Create a file to hold the serialized eConnect XML document
FileStream fs = new FileStream(filename, FileMode.Create);
XmlTextWriter writer = new XmlTextWriter(fs, new UTF8Encoding());

// Serialize the eConnect document object to the file using the XmlTextWriter.
XmlSerializer serializer = new XmlSerializer(eConnect.GetType());
serializer.Serialize(writer, eConnect);
writer.Close();
}
//If an eConnect exception occurs, notify the user
catch (eConnectException ex)
{
Console.Write(ex.ToString());
}

}
}
}

// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)

I hope this post helps if you need to use custom XML nodes with your eConnect integrations.

Chris