Wednesday, September 15, 2010

CandyWrapper 101: Why Use It?

One of my more popular contributions to the SugarCRM community is something I've dubbed CandyWrapper.  If you are not familiar with it, give its project page a look over at

The basic premise for its existence is to help minimize the amount of work required to interact with the SugarCRM SOAP API when programming in .NET.  It accomplishes this task by minimizing the amount of code a programmer needs to write in order to interact with the SugarCRM SOAP API.

Second to this, it eliminates the need to know intricacies of the SugarCRM SOAP API.  This is helpful for developers that may be well versed in .NET languages such as C#, but perhaps have never worked with SugarCRM's API.  Rather than having to sift through documentation and tedious trial-and-error scenarios to determine the manner in which the SugarCRM SOAP API expects things, CandyWrapper presents a standard approach and does all the dirty work behind the scenes.

But, exactly what does that mean?  

Let us take a quick look at a C# example to illustrate the advantages of using CandyWrapper.  Within it we will take a look at both the standard C# code one would use without CandyWrapper and of course, we will also look at code that takes advantage of it.  

Our example addresses the common need of logging into SugarCRM via the SOAP API.

First, the standard code, which assumes our web reference to the SugarCRM SOAP API has already been configured with the proper URL.

Standard approach:
private SugarCRM.sugarsoap oSugarCRM = new SugarCRM.sugarsoap();

string sUser = "myuser";
string sPass = "mypassword";
string sVersion = "1.0";
string sAppName = "TestApp";
SugarCRM.user_auth oSugarUserAuth = new SugarCRM.user_auth();
SugarCRM.set_entry_result oSugarSetEntryRes = new SugarCRM.set_entry_result();

//getMD5Hash is a custom function 
string sPassHash = this.getMD5Hash(sPass); 
string sResult = string.Empty;

//Define login parameters (user, pass, etc.)
oSugarUserAuth.user_name = sUser;
oSugarUserAuth.password = sPassHash;
oSugarUserAuth.version = sVersion;

oSugarSetEntryRes = oSugarCRM.login(oSugarUserAuth, sAppName);

//Get and return result (Session ID)
sResult =;
return sResult;

Of course, you would probably want to add some additional code to do error checking and the like, but it not necessary for our example.  Now, let us take a look at what you would need to do were using CandyWrapper.  The example assumes CandyWrapper has been added to the project as a reference.

CandyWrapper approach:

CandyWrapper.CandyWrapper oTest = new CandyWrapper.CandyWrapper();

//This line sets the URL for the SOAP web service
int iTemp = oTest.setURL(""); 

string sSession = oTest.doLogin("myuser", "mypassword", "1.0", "TestApp");

That's it!

Other tasks, such as adding or modifying records, etc. are equally simplified and should help you get up and running faster and reduce the amount of effort required to complete your projects.

So which approach do you prefer? 


  1. Hey there, I happen to have found a small bug that the code seems to default all modules passed into the Candy Wrapper turn the first character of its name into Upper Case. This is fine for standard modules, but when it comes to custom modules it becomes an issue. An example is provided in the project's forums where a custom module chwv_Venues turns into Chwv_Venues which then doesn't return anything because that module can not be found.

  2. Ah, yes. You are correct. Apologies about that.

    I'll give it a look and correct it.

    Ironically, the reason why I coded it that way is to avoid potential problems users may run into due to differences between how the Sugar SOAP API works when the server is Windows versus a case-sensitive OS like Linux.

    Under the latter, a reference to the "contacts" module would fail, although it would work on Windows.

  3. FYI, I haven't had a chance to correct the problem yet as I've been tied up with other projects.

    However, I did put the code out on GitHub over the weekend. See here:

  4. Hey there Angel,
    Thanks a million for this library. Certainly made my job of connecting to Sugar a breeze - whereas just last night I was tearing my hair with the native SOAP calls of C#.

    Got a question - is there a way to debug the calls? Or see a live dump of the soap packets? That'll be very helpful indeed.


  5. @Micro:

    You are welcome. Glad to hear you are finding it of help.

    The wrapper itself doesn't operate at that low of a level so it doesn't have a way of displaying the SOAP packets, nor does it yet have debugging built in (on task list).

    However, you should be able to use something like Fiddler to sniff it.

    And if you are interested, the source to the wrapper is also available on Github:

  6. Hi Angel,

    I appreciate the work you've done as I've been struggling with the API.

    I'm not clear (from looking at your code) how to determine if a login is successful. It looks like the doLogin() method should return a session id. However, it might also return an error number if login fails. Since I don't know what might be returned by set_entry_result.error.number, how do I determine a valid session id?


  7. @Fang:

    A session ID looks somewhat similar to a GUID. It is usually something like this:


    I don't know what the rules are (if any) as far as which letters/numbers are allowed, but as you can see, it is longer than the 2 digit number you would normally get if there was an error/problem.

  8. Hi Angel,

    I tried using candy wrapper with SugarCRM 6.5 but the API is different. But what I really wanted to ask was is there a way to add a user in a role using soap in C#? if there is, can you give me a example, because I've been looking around the net and with no luck could'nt find one. I really really appreciate it.

    Thanks Roy

    1. It doesn't support the newer versions of the API yet. If you use /soap.php vs. /service/v4/soap.php, it will work, regardless of the version of SugarCRM.

      I've never tried doing that via the API. You can try using set_relationship using the corresponding ACLRoles and Users records, but I don't know if that will work for sure.

  9. Hi Angel,

    Thanks for the reply, if I'm going to use set_relationship can you give me an example on how set the parameters in C#.

    Thanks a lot

  10. GetEntryList is not working in any of the method.
    candy wrapper shows 0 as result.
    In second approach its showing there is error in XML document. I am using V2 version.

    1. CandyWrapper currently only supports v1 of the API (http://your_url/soap.php). This is likely the reason why it is failing for you.


Your comments, feedback and suggestions are welcome, but please refrain from using offensive language and/or berating others. Thank you in advance.