Click here to Skip to main content
15,881,594 members
Articles / Programming Languages / C#
Article

Access Basecamp Through .NET API Wrapper

Rate me:
Please Sign up or sign in to vote.
4.20/5 (6 votes)
8 Dec 20062 min read 52.4K   491   16   19
This API will make submission to Basecamp easier by converting returned responses into .NET objects.

Introduction

This wrapper simplifies calls to the Basecamp API by returning .NET objects.

How I Built It

  1. First, I created a class for each response type returned by the Basecamp API.

    • AbbreviatedPost
    • AttachmentCategory
    • Comment
    • Category
    • Milestone
    • Person
    • Post
    • PostCategory
    • Project
    • TodoItem
    • TodoList

    Each of these classes then provided a static method that can parse an XML response into a generic list of that type.

    C#
    public static IList<Project> Parse(XmlNodeList projectNodes)

  2. Next, I created the BasecampManager class that would do the work to format the request, parse the response, and return the desired object.

    C#
    public IList < Project > GetProjects() 
    {
        string cmd = "/project/list"; 
        IList<Project> projects = null;
        if (IsInitialized())
        {
            XmlDocument xml = SendRequest(cmd, "");
            projects = Project.Parse(xml.SelectNodes("//project"));
        }
        return projects;
    }
  3. Next, I needed to handle requests that required an input request XML string.

    I accomplished this, by adding another static method to the specific domain classes that could generate an XML request string from an incoming set of parameters.

    C#
    public static string CreateCommentRequest(int postID, string body)
    {
        System.IO.StringWriter sw = new System.IO.StringWriter();
        XmlWriter w = new XmlTextWriter(sw);
        w.WriteStartElement("request");
        w.WriteStartElement("comment");
        w.WriteStartElement("post-id");
        w.WriteString(postID.ToString());
        w.WriteEndElement(); //end postID
        w.WriteStartElement("body");
        w.WriteString(body);
        w.WriteEndElement(); //end body
        w.WriteEndElement(); //end comment
        w.WriteEndElement(); //end request
        return sw.ToString();
    }

    I called this method then from my BasecampManager when I needed to create a Basecamp comment:

    C#
    public Comment CreateComment(int projectID, int postID, string body)
    {
        string cmd = "/msg/create_comment";
        string request = Comment.CreateCommentRequest(postID, body);
        XmlDocument xml = SendRequest(cmd, request);
        Comment comment = null;
        IList<Comment> comments = 
                Comment.Parse(xml.SelectNodes("//comment"));
        if (comments.Count > 0)
        {
            comment = comments[0];
        }
        return comment;
    }

  4. I then repeated this process for each request/response that I wished to implement.

How To Use It

Step 1) Initialize connection information

Option 1: Use an application configuration file

  • basecamp_projectURL: project URL excluding the HTTP/HTTPS prefix
  • basecamp_userName/basecamp_password: user/password that has access to the desired project
  • basecamp_secureMode: true if using HTTPS, false otherwise

    C#
    BasecampManager b = new BasecampManager();

Option 2: Set connection details at construction

C#
BasecampManager b = new BasecampManager(url, username, pwd, secure);

Option 3: Override configuration values

C#
BasecampManager b = new BasecampManager();
b.Url = "myproject.projectpath.com";
b.Username = "myusername";
b.Password = "mypassword";
b.SecureMode = false;

Step 2) Call Methods to Retrieve/Update Data

C#
IList <Project> projects = b.GetProjects();

That's it! Have fun investigating and using the other methods I wrapped. I hope you find this very simple and hopefully useful.

What I Didn't Do and What You Might Want To Improve

  • There are a couple places in the Basecamp API that different responses contain slightly different object signatures. For example: Company is returned differently when contained in a project than when selecting a list of companies. I created a couple constructors that take this into account, but may have missed some of the finer points on this one.
  • There are also some attributes that don't get passed depending on the requestor's permission level. For now, I only wrap these in a try/catch that swallows any exceptions. Person.Parse is a good example of this.
  • I had some DateTime variables that I had to set to 1/1/1900 instead of null. Person.Parse is a good example of this.
  • I did not implement time-tracking or some of the modify (update/add/delete) for all methods.
  • While I tested the methods, I found that updating/deleting comments was not working. I'm not sure if this was me, or something with the Basecamp API.
  • You may find that your Basecamp data causes unhandled exceptions when trying to load the .NET objects since you may have data in your projects that I do not and did not test.

Credit

I must give credit for the beginning implementation of BasecampManager. I used the API I found by Munsifali Rashid at http://www.munit.co.uk/blog/2006/04/17/c-wrapper-for-basecamp-api/. I modified it slightly according to a post on the Basecamp forum:

C#
webRequest.ServicePoint.Expect100Continue = false;

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    United States United States
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    QuestionHow to download files which are uploaded today from all projects Pin
    nirajzambad12-Feb-14 3:42
    nirajzambad12-Feb-14 3:42 
    Questionthe remote server returned an error (500) internal server error Pin
    nirajzambad22-Jan-14 22:50
    nirajzambad22-Jan-14 22:50 
    AnswerRe: the remote server returned an error (500) internal server error Pin
    Niteen Jadhav26-Feb-14 3:23
    Niteen Jadhav26-Feb-14 3:23 
    Questionserver forbidden error while getting the response Pin
    dharamveer pal27-Feb-13 2:01
    dharamveer pal27-Feb-13 2:01 
    Questionserver forbidden error while getting the response Pin
    dharamveer pal27-Feb-13 2:00
    dharamveer pal27-Feb-13 2:00 
    QuestionAbout basecamp command. Pin
    baiju@ispg.in6-Feb-13 19:08
    baiju@ispg.in6-Feb-13 19:08 
    GeneralSearch documents Pin
    CurtWRC31-Mar-10 4:44
    CurtWRC31-Mar-10 4:44 
    GeneralNice work and a Little bug Pin
    Member 15589429-Jul-09 11:23
    Member 15589429-Jul-09 11:23 
    GeneralRe: Nice work and a Little bug Pin
    JoeSox28-May-10 6:48
    JoeSox28-May-10 6:48 
    GeneralWorks well, how can i contribute adaptation to VS2008 Pin
    michael kariv24-Sep-08 9:06
    michael kariv24-Sep-08 9:06 
    GeneralThanks - working great Pin
    Ryan Farley17-Mar-08 18:52
    Ryan Farley17-Mar-08 18:52 
    GeneralHaving trouble using the API Pin
    Amhed Herrera4-Jun-07 13:48
    Amhed Herrera4-Jun-07 13:48 
    GeneralBug in TodoItem.cs Pin
    dave@davefrank.com9-Jan-07 6:29
    dave@davefrank.com9-Jan-07 6:29 
    GeneralCannot send a content-body with this verb-type. Pin
    johnstrait114-Dec-06 10:17
    johnstrait114-Dec-06 10:17 
    GeneralRe: Cannot send a content-body with this verb-type. Pin
    Loyll2129-Dec-06 8:30
    Loyll2129-Dec-06 8:30 
    GeneralRe: Cannot send a content-body with this verb-type. Pin
    CurtWRC31-Mar-10 4:40
    CurtWRC31-Mar-10 4:40 
    GeneralRe: Cannot send a content-body with this verb-type. Pin
    Member 803094623-Jun-11 9:16
    Member 803094623-Jun-11 9:16 
    GeneralRe: Cannot send a content-body with this verb-type. Pin
    guideX22-Mar-12 14:02
    guideX22-Mar-12 14:02 
    GeneralRe: Cannot send a content-body with this verb-type. Pin
    guideX22-Mar-12 15:55
    guideX22-Mar-12 15:55 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.