Zoho CRM REST API

I have about a dozen programming-related items floating around in my head that I’d like to write up short blog entries about. Maybe I’ll manage to get one or two written up tonight.

I’ve been doing some work recently with some random REST APIs. When I’m calling REST APIs from .NET, I like to use EasyHttp. Based on the stats on its NuGet page, I guess it’s not that popular, but it’s updated often enough, and it works well for me.

I recently worked on a project where I had to create a lead in Zoho CRM, using their API. I had a little bit of trouble, but only because I didn’t have quite the right parameters set — it turns out that “newformat=1” is really important. I had looked for some sample C# code for the Zoho API when I started this, and didn’t find any, so I thought I’d post a quick Gist with my code:

/*
 * Sample C# code to create a lead with the Zoho CRM API.
 * ajh 2012-08-23
 */
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Dynamic;
using System.Linq;
using System.Net;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using EasyHttp.Http;
using log4net;

namespace Sample.Web
{
    public class ZohoCrm
    {
        static string ZohoApiBaseUrl = "https://crm.zoho.com/crm/private/xml/Leads/insertRecords"; 
        static string ZohoApiKey = ConfigurationManager.AppSettings["ZohoApiKey"];

        public static bool CreateLead(BLL.SampleLead sl)
        {
            ILog _log = log4net.LogManager.GetLogger("ZohoCrm/CreateLead");

            XDocument xmlData = new XDocument(
            new XElement("Leads",
                new XElement("row", new XAttribute("no", "1"),
                    new XElement("FL", new XAttribute("val", "Lead Source"), "Trial Signup"),
                    new XElement("FL", new XAttribute("val", "Company"), sl.CompanyName),
                    new XElement("FL", new XAttribute("val", "Last Name"), sl.Name),
                    new XElement("FL", new XAttribute("val", "Email"), sl.EMail)
                )));

            string url = string.Format("{0}?authtoken={1}&scope=crmapi&newFormat=1&xmlData={2}", 
				ZohoApiBaseUrl, ZohoApiKey, 
                HttpUtility.UrlEncode(xmlData.ToString()));

            var http = new HttpClient
            {
                Request = { Accept = HttpContentTypes.ApplicationXml }
            };

            dynamic emptyPost = new ExpandoObject();            
            EasyHttp.Http.HttpResponse response;
            try
            {
                response = http.Post(url, emptyPost, HttpContentTypes.ApplicationXml);
            }
            catch (WebException ex)
            {
                _log.ErrorFormat("Error: WebException - {0}", ex.Message);
                return false;
            }

            if (response.StatusCode != HttpStatusCode.OK)
            {
                _log.InfoFormat("Response = {0} - {1}", response.StatusCode, response.StatusDescription);
                _log.Info(response.RawText);
                return false;
            }

            XDocument xdoc;
            try
            {
                xdoc = XDocument.Parse(response.RawText);
            }
            catch (XmlException ex)
            {
                _log.ErrorFormat("Error: XmlException parsing API response - {0}", ex.Message);
                _log.Info(response.RawText);
                return false;
            }

            string msg;
            try
            {
                msg = xdoc.Descendants("result").First().Element("message").Value;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Error: Exception reading from API response - {0}", ex.Message);
                _log.Info(response.RawText);
                return false;
            }
            if (msg != "Record(s) added successfully")
            {
                _log.InfoFormat("Unexpected XML result: {0}", msg);
                _log.Info(response.RawText);
                return false;
            }

            return true;
        }
    }

(See also this Gist.)

I’m also using log4net here.  I’m a really big fan of log4net, and I use it in almost all of my projects. I have a pretty standard log.config file I use that sets up a RollingFileAppender, with ten files of 100k each. That’s usually enough to keep a few days or weeks worth of history, depending on the level of logging and the level of activity. And I never have to worry about the log files growing out of control; they just keep rolling over. I think log4net is pretty popular, based on the numbers on their NuGet page.

I try to do a lot of error-handling whenever I’m dealing with a REST API. There are plenty of things that can go wrong. You can see in the code above that I try to trap anything that might throw an exception and log it. I’m never sure if I’m doing this the “right” way. I know some people, when writing a routine like this, would just let the exceptions happen, then have a try/catch around the call to the CreateLead method, and deal with it at a higher level.

Fractions!

I haven’t posted much code to my blog lately, so I thought I’d pass along some general-purpose C# code that I recently used in a project. I’m working on a system right now where the original author made some, shall we say, interesting decisions about how to store data in SQL. Specifically, he used varchar fields for most of the numeric data. And, in those fields, he sometimes stores the data in decimal format (e.g. “1.5”), sometimes as fractions (e.g. “1 1/2”) and sometimes as explicitly-signed fractions (“+1 1/2”).  I, of course, need to do LOTS of math on these numbers. The decimal fields can be dealt with using good old TryParse and ToString of course, but there’s no obvious parse routine for fractions, nor is there an obvious way to turn a decimal number back into a fraction string.

The internet, of course, provides. Here is a VB.NET function to turn a fraction string into a decimal and there is some C# code to convert a decimal into a fraction string in this thread. I converted the VB.NET to C#, and cleaned both of them up and put them in a utility class.  Here it is:

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

namespace MySuit.MySuitV2.BLL
{
    public class Utility
    {
        public static decimal FractionToDecimal(string frac)
        {
            // this method should convert a fraction, e.g. "12 1/4" to a decimal, e.g. 12.25.
            // based on http://amrelgarhytech.blogspot.com/2008/03/fraction-to-decimal.html
            // TODO: not sure how best to handle exceptions here. (parse errors, div by zero, null/empty string input...)
            decimal rv;
            int numerator, denominator, wholePart = 0;
            int sign = 1;

            if (string.IsNullOrEmpty(frac))
                return 0m;

            // deal with signs
            frac = frac.Trim().TrimStart('+');
            if (frac[0] == '-')
            {
                frac = frac.TrimStart('-');
                sign = -1;
            }
            frac = frac.Trim();

            if (frac.IndexOf("/") > 0)
            {
                if (frac.IndexOf(" ") > 0)
                {
                    wholePart = int.Parse(frac.Substring(0, frac.IndexOf(" ")));
                    frac = frac.Substring(frac.IndexOf(" "));
                }
                numerator = int.Parse(frac.Substring(0, frac.IndexOf("/")));
                denominator = int.Parse(frac.Substring(frac.IndexOf("/") + 1));
                rv = sign * (wholePart + ((decimal)numerator / denominator));
            }
            else
            {
                rv = decimal.Parse(frac);
            }
            return rv;
        }

        public static string DecimalToFractionSigned(decimal value)
        {
            // always put a sign (+/-) in front
            string rv = DecimalToFraction(value);
            if (rv[0] != '-')
                rv = string.Format("+{0}", rv);
            return rv;
        }

        public static string DecimalToFraction(decimal value)
        {
            // taken from here: http://bit.ly/tHaKrK and modified to work with negative numbers too.

            int sign = 1;
            if (value < 0)
            {
                value = Math.Abs(value);
                sign = -1;
            }

            // get the whole value of the fraction
            decimal mWhole = Math.Truncate(value);

            // get the fractional value
            decimal mFraction = value - mWhole;

            // initialize a numerator and denominator
            uint mNumerator = 0;
            uint mDenominator = 1;

            // ensure that there is actually a fraction
            if (mFraction > 0m)
            {
                // convert the value to a string so that you can count the number of decimal places there are
                string strFraction = mFraction.ToString().Remove(0, 2);

                // store the number of decimal places
                uint intFractLength = (uint)strFraction.Length;

                // set the numerator to have the proper amount of zeros
                mNumerator = (uint)Math.Pow(10, intFractLength);

                // parse the fraction value to an integer that equals [fraction value] * 10^[number of decimal places]
                uint.TryParse(strFraction, out mDenominator);

                // get the greatest common divisor for both numbers
                uint gcd = GreatestCommonDivisor(mDenominator, mNumerator);

                // divide the numerator and the denominator by the greatest common divisor
                mNumerator = mNumerator / gcd;
                mDenominator = mDenominator / gcd;
            }

            // create a string builder
            StringBuilder mBuilder = new StringBuilder();

            // add the whole number if it's greater than 0
            if (mWhole > 0m)
            {
                mBuilder.Append(mWhole);
            }

            // add the fraction if it's greater than 0m
            if (mFraction > 0m)
            {
                if (mBuilder.Length > 0)
                {
                    mBuilder.Append(" ");
                }

                mBuilder.Append(mDenominator);
                mBuilder.Append("/");
                mBuilder.Append(mNumerator);
            }

            if (sign == -1)
                mBuilder.Insert(0, '-');

            return mBuilder.ToString();
        }


        private static uint GreatestCommonDivisor(uint valA, uint valB)
        {
            // return 0 if both values are 0 (no GSD)
            if (valA == 0 && valB == 0)
            {
                return 0;
            }
            // return value b if only a == 0
            else if (valA == 0 && valB != 0)
            {
                return valB;
            }
            // return value a if only b == 0
            else if (valA != 0 && valB == 0)
            {
                return valA;
            }
            // actually find the GSD
            else
            {
                uint first = valA;
                uint second = valB;

                while (first != second)
                {
                    if (first > second)
                    {
                        first = first - second;
                    }
                    else
                    {
                        second = second - first;
                    }
                }

                return first;
            }
        }

    }
}

(This is also in a Gist.)
I hope this helps anyone who might be looking for something similar. Also, I want to reiterate that I didn’t write this code from scratch. I took two existing functions, one in VB and one in C#, converted the VB to C#, cleaned them both up a bit, and put them together.

Luckily, by the way, all of the fractions I’m dealing with resolve to simple decimal numbers; everything is x/2, x/4, or x/8. I don’t have to deal with converting 1/3 to decimal and back. If you need to do that, you probably want a class that stores the fractions as numerator and denominator, and does math on them, as fractions.  There are a couple of those out there, if you look around.

reference vs. value types, and LINQ

One of the people I work with was having some trouble with reference vs. value types (in C#) this week. This article seems to give a pretty clear explanation of how these things work. Always good to have a little refresher on the fundamentals.

And, in poking around on this guy’s web site, I found LINQPad, a tool for executing LINQ queries. I have to admit that I haven’t had any time to play around with LINQ at all, but I’m really curious about it. I like his idea of trying to do all your ad-hoc SQL queries in LINQ for a week, to force yourself to start getting used to it. Some of the stuff I’m doing this week is requiring me to do a *lot* of ad-hoc SQL, though. My brain is so completely wired for T-SQL at this point that I think I’d get really frustrated really quickly trying to use anything else.

computer books

I just finished ASP.NET 2.0: A Developer’s Notebook. Looking back through old posts, it appears that I’ve been working my way through this one for quite a while now. Oh well. The next book in my stack is Expert C# Business Objects which, according to Amazon, I bought on Sept 20, 2005. So I guess it’s about time to crack it open, right? Of course the C# 2005 version is out now. I’d like to read that one instead, but I don’t want to just toss out a $60 computer book. I guess I’ll start reading the one I’ve got, then maybe think about “upgrading” to the new one if it’s really interesting.

learning C#

I think I’ve finally finished converting my little calculator program from C++ to C#. The last stumbling block was figuring out how to substitute standard input with the contents of a string that had been passed on the command-line. The answer was to declare a TextReader object, then assign it to Console.In when I wanted to read from the console, or a StringReader object when I wanted to read from a string. Easy! (Once you’ve figured out that there’s such a thing as a StringReader object, and that it’s interchangeable with Console.In.)

pet project

I made a little progress on my pet C# project tonight. It’s a little command-line calculator that I’m converting from C++. It now adds, subtracts, multiplies, and divides! Next, I need to reimplement the function handling (square root, cos, tan, etc). That’s going to be interesting, since I was using function pointers for that, and now I’m going to have to figure out delegates, since C# has no function pointers.

Mr. Productivity

I just spent the last 2 hours working on converting an old C++ program to C#. I sorta like C#, but this particular program used every part of C++ that C# trashed or changed drastically: function pointers, unions, friend classes, oddball stream handling, and other stuff like that. That’s good, of course, since the whole point of this exercise is to learn C#. Actually, I haven’t used C++ in so long, I don’t remember what some of the fancy stuff in this program is doing anyway.