in c# .Net Web services salesforce ~ read.
Integrating .Net and Salesforce, part 2: The Metadata API

Integrating .Net and Salesforce, part 2: The Metadata API

Note: all the code for this example is found on Github

It's been over 1 year since I wrote my first post on integrating Salesforce and .Net, so it's about time I created the second entry in the series.

In this article we want to explore the Salesforce metadata API. The end goal is querying, creating and modifying metadata programmatically from a C# app. I haven't found a single, working, end-to-end example, so I thought it would be a good time to create my own.

The metadata API

The Salesforce API, available both in REST and SOAP flavours, allows us to modify the data in the a Salesforce org: we can create and modify contacts, accounts, etc.

However, what it does not allow is to modify what Salesforce calls metadata: custom object definitions, custom fields, permissions sets, etc. If we want to modify these (for instance, to programmatically create a new custom object, or add a field to an existing object), then we need to use the Metadata API.

This API is only available as a SOAP service. There is no REST equivalent. Furthermore, it is not accessible from Apex code, so the only way to programmatically modify your metadata is to connect to the metadata API via SOAP. Tools such as the Force.com migration tool or sfdx are consumers of this API.

Note that this API does not expose login or logout facilities. We need to use the Enterprise SOAP API for that.

In Salesforce there are many types of metadata. For the purpose of this article we will focus on custom objects only.

Download the WSDLs

Since we're consuming SOAP web services, we will need the WSDL files that describe them. They are not accessible over http; instead, we'll have to download them.

  • Log onto your Salesforce org
  • Navigate to Setup
  • Type "API" in the Quick Find box
  • Click on the API option
  • Click Generate Metadata WSDL and save the WSDL file locally. We'll need it later
  • Click Generate Enterprise WSDL and save it locally

Open the WSDLs in your solution

In Visual Studio, create a new Console application solution. Then reference the WSDLs as follows:

  • Add Service Reference
  • Type in the path of your file
  • Select a Name to be used as a namespace, and Save
  • Repeat for both files

I used the names SalesforceEnterpriseClient and SalesforceMetadataClient for both autogenerated classes.

Note that the WSDL files are not usable out-of-the box. There is an issue either in the file formats or in the way .Net reads them. The autogenerated C# code needs to be edited, and all occurrences of 2-dimensional array "[][]" need to be replaced by unidimensional arrays "[]".

You will need to "show all files" in Visual Studio to be able to see the codegenerated files.

Note that the GitHub code already contains the modified files.

Using the WSDLs

Since the WSDL's are a bit clunky to use, I decided to create a façade class that allows us to access metadata easier. This class is called MetadataClient, will expose methods for logging in, manipulating metadata, and logging out.

Authentication

Surprisingly, authenticating via the SOAP API is easier than with the REST API. All we need are credentials and we're ready to go. There is no need to create a connected App to log on via the SOAP API.

I have decided to store the credentials in the App.config file, to avoid having to supply them every time we connect.

The MetadataClient uses the Enterprise WSDL to log on. After login, the service returns a Session ID and the URLs to use for further calls to the SOAP API and the Metadata API. We store all this data in our class for further operations.

Manipulating metadata

We have created 3 methods to get, create and delete metadata. And just to make the class easier to use, we have created 3 overloads for the same operations for custom objects.

Retrieving metadata

Retrieving metadata is fairly easy:

We reuse the data we obtained after login (sessionId, metadataUrl...) in our SOAP request.

We've also created a friendly overload to get custom object data.

Creating metadata

This is when things get more interesting: to create a custom object definition, we need to create the full definition in memory and send it with the request.

We have populated only the required fields, including a name field:

Note that you need some subtle things for this to work. Due to the way in which .Net deals with WSDLs and optional properties, you need to set the "valueSpecified" field of said properties, or the value will not be sent to Salesforce, causing an error. More info can be found here.

Deleting metadata

Deleting metadata is simple:

Logging off

We use the SOAP API web service again to log off, indicating the session ID we want to log off from.

I have implemented the IDisposable interface to ensure we log off and the resources are freed every time the object is disposed of.

Add nice command-line options

I wanted to create some command-line verb syntax to allow us to create, retrieve and delete metadata. I've decided to use the CommandLineParser NuGet package, which offers a nice way to do this.

All that the main method does is parse the arguments and call the right method in our façade class.

Good To Go!

With this in place, we can now run:

sfmd create -o Test -l "Test object" -p "Test objects"

We see this response in the console:

Logged in with session ID: (session Id here)
Test__c: Success!
Logged out of session ID (session Id here)

If we now log onto our org, in Custom Objects, we can see a new object called "Test object". Success!

We can retrieve the data by doing

sfmd get -o Test

Which returns this:

Logged in with session ID: (session Id here)
Test__c
  Name field: sfmd.SalesforceMetadataClient.CustomField
Logged out of session ID (session Id here)

And finally we can delete our custom object by running

sfmd delete -o Test__c

Which returns:

Logged in with session ID: (session Id here)
Test__c: Success!
Logged out of session ID (session Id here)

We can now see that the custom object has been deleted

Possibilities

This is a small proof of concept, showing how to connect to the Metadata API end-to-end. This is in no way production code: the code is riddled with informational messages to the console, there are many failure points and no unit tests.

Nevertheless, this opens the doors to many possibilities. This shows how you can completely define or modify an object model from an external .Net app. You can integrate external applications with Salesforce, to the point that when your users modify metadata in your external app, changes can be reflected in Salesforce.

I hope you find this useful.