Simon Fell > Its just code > May 2008

Saturday, May 3, 2008

I discovered a new Salesforce related blog today, and noticed that they spread the seeming popular meme that the metadata API doesn't work on standard objects, so just clarify that that's wrong, here's a .NET example that adds a new custom field to the standard Account object.

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

namespace metadata
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("useage: metadataDemo username password");
                return;
            }
            MetadataCreator mc = new MetadataCreator(args[0], args[1]);
            mc.Create();
        }
    }

    class MetadataCreator
    {
        private metaforce.MetadataService ms;
        private sforce.SforceService ss;

        public MetadataCreator(String username, String password)
        {
            ss = new sforce.SforceService();
            sforce.LoginResult lr = ss.login(username, password);
            
            ss.Url = lr.serverUrl;
            ss.SessionHeaderValue = new sforce.SessionHeader();
            ss.SessionHeaderValue.sessionId = lr.sessionId;

            ms = new metaforce.MetadataService();
            ms.Url = lr.metadataServerUrl;
            ms.SessionHeaderValue = new metaforce.SessionHeader();
            ms.SessionHeaderValue.sessionId = lr.sessionId;
        }

        public void Create()
        {
            metaforce.CustomField cf = new metaforce.CustomField();
            cf.description = "Favorite fruit";
            cf.fullName = "Account.favFruit__c";
            cf.label = "Fav Fruit";
            cf.type = metaforce.FieldType.Text;
            cf.length = 25;
            cf.lengthSpecified = true;

            metaforce.AsyncResult r = ms.create(new metaforce.Metadata[] { cf })[0];
            while(!r.done) {
                System.Threading.Thread.Sleep(r.secondsToWait * 1000);
                r = ms.checkStatus(new string[] { r.id })[0];
            }
            if (r.state == metaforce.AsyncRequestState.Error) 
                Console.WriteLine("Error : {0} {1}", r.statusCode, r.message);
            else {
                Console.WriteLine("Done, added new field to Account");
            }
        }
    }
}