Access Basecamp Through .NET API Wrapper






4.20/5 (6 votes)
Dec 8, 2006
2 min read

53909

491
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
- 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.public static IList<Project> Parse(XmlNodeList projectNodes)
- Next, I created the
BasecampManager
class that would do the work to format the request, parse the response, and return the desired object.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; }
- 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.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 aBasecamp
comment: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; }
- 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 prefixbasecamp_userName
/basecamp_password
: user/password that has access to the desired projectbasecamp_secureMode
:true
if using HTTPS,false
otherwiseBasecampManager b = new BasecampManager();
Option 2: Set connection details at construction
BasecampManager b = new BasecampManager(url, username, pwd, secure);
Option 3: Override configuration values
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
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 to1/1/1900
instead ofnull
.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:
webRequest.ServicePoint.Expect100Continue = false;