Getting Started Guide: How to query Marketo’s SOAP APIs in C#
This document details how one can get started quickly with Marketo’s SOAP APIs using a C# application. Marketo’s SOAP documentation while adequate doesn’t provide enough details on how to get started, especially in C#. The steps I have laid out below will allow any developer to quickly understand Marketo’s SOAP model and develop his/her own light weight C# application to query Marketo data from the cloud.
The Key to the SOAP Model:
The key to your soap model is in understanding the WSDL (Web Service Description Language). The WSDL is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information. Think of the WSDL like a blue print and if you’re a C# programmer the bells should be ringing now – “blue print means a class definition for an object!” You got it! The WSDL provides the definition that makes it easy to handle everything as an object. The example below will make it clear.
Steps to get started in creating your C# application
3. Enter your Endpoint URL followed by a ‘?WSDL’ in the address bar and click GO. If you do not know what your Endpoint URL is, then please refer to the following web page on Marketo to determine your client credentials (Marketo SOAP APIs » Marketo Developers) http://developers.marketo.com/documentation/soap/
4. When you click Go, Visual Studio will query the WSDL that’s been published by Marketo and provide the following object model
5. Name the Service "MKTOSoapService".
Click “OK”. This will now be added to your Solution Explorer window as a Service Reference which you can then query through the object model.
NOTE: This is an example on how to use the SOAP APIs. If you are interested in the REST APIs, let me know and I will post something for REST as well using C#
Creating your program.cs file
The following is a simple example on how to use the Service Reference to query Marketo.
Note: I would like to acknowledge MurtzaM. I used some of his code below to create this example. His examples are available at https://github.com/Marketo/C-Sample-Code
using System;
using System.Security.Cryptography;
namespace TestSoapApplication
{
class Program
{
static void Main(string[] args)
{
/* MktowsPort is an abstract class and cannot be instantiated as an object.
Use MktowsPortClient as the class to instantiate. The format of theobject is <namespace><class> */
MKTOSoapService.MktowsPortClient client = new MKTOSoapService.MktowsPortClient();
MKTOSoapService.AuthenticationHeaderInfo mktoHeader = new MKTOSoapService.AuthenticationHeaderInfo();
/* authentication */
mktoHeader.mktowsUserId = "<Your Marketo SOAP UserID>";
string encryptionKey = "<Your Shared Secret - encryption key from Marketo Web Admin>";
/* the requestTimeStamp should be current. You cannot put a date in the past */
string requestTimeStamp = Helper.ConvertDateToW3CTime(DateTime.Now);
string stringToEncrypt = requestTimeStamp + mktoHeader.mktowsUserId;
string results = null;
/* you will need to encode the Shared Secret and the requestTimeStamp, cast to HMACSHA1 which is required by Marketo. This will then produce the
requiredSignature which is passed in through the SOAP envelope header */
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(encryptionKey);
HMACSHA1 hmacsha1 = new HMACSHA1(keyByte);
byte[] messageBytes = encoding.GetBytes(stringToEncrypt);
byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
/* build SOAP envelope header */
string header = Helper.ByteToString(hashmessage);
mktoHeader.requestSignature = header.ToLower();
mktoHeader.requestTimestamp = requestTimeStamp;
/* use the SOAP WSDL to construct your objects */
MKTOSoapService.ParamsGetLead mktoLeads = new MKTOSoapService.ParamsGetLead();
MKTOSoapService.LeadKey mktoleadkey = new MKTOSoapService.LeadKey();
/* Create a LeadKeyReference object */
mktoleadkey.keyType = MKTOSoapService.LeadKeyRef.IDNUM; /* IDNUM is the Marketo Lead ID */
mktoleadkey.keyValue = "<enter your lead ID value here>";
mktoLeads.leadKey = mktoleadkey;
MKTOSoapService.ResultGetLead rs = new MKTOSoapService.ResultGetLead();
try
{
/* here we are using the getLead function/API call. It needs the header and the Lead object */
MKTOSoapService.SuccessGetLead response = client.getLead(mktoHeader, mktoLeads);
rs = response.result;
if (response.result.count > 0)
{
Console.WriteLine("Lead found");
MKTOSoapService.LeadRecord[] leadRecord = response.result.leadRecordList;
/* use the LeadRecord class to parse through each Lead returned */
foreach (MKTOSoapService.LeadRecord ldrec in leadRecord)
{
Console.WriteLine(ldrec.Id);
Console.WriteLine(ldrec.Email);
/* use the Attribute class to unpack every data point (i.e. IDNUM, email, FirstName, LastName, InferredCompany, City, State, Country etc.*/
foreach(MKTOSoapService.Attribute ldattrib in ldrec.leadAttributeList)
{
Console.WriteLine(ldattrib.attrName + "-" + ldattrib.attrValue);
}
}
Console.ReadLine();
}
else
{
Console.WriteLine("Lead not found");
Console.ReadLine();
}
}
catch (Exception e)
{
results = e.Message;
rs = null;
}
}
}
}
==================<HELPER CLASS>====================
Coutesy of MurtzaM from https://github.com/Marketo/C-Sample-Code
using System;
namespace TestSoapApplication
{
class Helper
{
#region supporting Functions
public static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
public static string HashCode(string str)
{
string rethash = "";
try
{
System.Security.Cryptography.SHA1 hash = System.Security.Cryptography.SHA1.Create();
System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
byte[] combined = encoder.GetBytes(str);
hash.ComputeHash(combined);
rethash = Convert.ToBase64String(hash.Hash);
}
catch (Exception ex)
{
string strerr = "Error in HashCode : " + ex.Message;
}
return rethash;
}
public static string ConvertDateToW3CTime(DateTime date)
{
var utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(date);
string w3CTime = date.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss");
w3CTime += "Z";
return w3CTime;
}
#endregion
}
}
Thanks, this is helpful!
I am interested in a Rest Example. Thank you