Shortening URLs With The bit.ly API Via ASP.NET

After yesterday’s post on using the Twitter API to post status updates on Twitter from an ASP.NET application, a follower of my client suggested using a URL shortening service to link to the articles headlines being posted as tweets.

That was an excellent idea of which I should have thought in the first place. And thanks to the extreme simplicity of the REST-like bit.ly API, shortening URLs is as simple as sending a request URL laced with querystring variables.

So here is a quick and simple ASP.NET subroutine, written in VB.NET, to shorten URLs with the bit.ly API:

Sub BitlyIt(ByVal strUser As String, ByVal strAPIKey As String, ByVal strLongUrl As String)
	'This subroutine requires your page to have a label control named lblStatus

	'build URL to shorten method resource
	Dim strUri As New StringBuilder("http://api.bit.ly/shorten?")
	strUri.Append("version=2.0.1")
	'we want to get an XML response back from bit.ly, not the default JSON
	strUri.Append("&format=xml")
	strUri.Append("&longUrl=")
	strUri.Append(Server.HtmlEncode(strLongUrl))
	strUri.Append("&login=")
	strUri.Append(Server.HTMLEncode(strUser))
	strUri.Append("&apiKey=")
	strUri.Append(Server.HTMLEncode(strAPIKey))

	'create request for shorten resource
	Dim objRequest As HttpWebRequest = WebRequest.Create(strUri.ToString())
	'since we are passing querystring variables, our method is get
	objRequest.Method = "GET"
	'act as though we are sending a form
	objRequest.ContentType = "application/x-www-form-urlencoded"
	'don't wait for a 100 Continue HTTP response from bit.ly
	objRequest.ServicePoint.Expect100Continue = False
	'since we are using get, we need not send a request body; set content-length to 0
	objRequest.ContentLength = 0

	'we need to capture the XML being sent in response
	'read the response into a new XML document
	Dim objResponse As WebResponse = objRequest.GetResponse()
	Dim objXML As New XmlDocument()
	objXML.Load(objResponse.GetResponseStream())

	'the response will have three node values we're primarily interested in
	'the errorCode node will contain a numeric error code; 0 means success
	Dim nErrorCode As XmlNode = objXML.SelectSingleNode("//errorCode")
	'if there was an error, the errorMessage node will contain a user-friendly message useful for debugging
	Dim nErrorMsg As XmlNode = objXML.SelectSingleNode("//errorMessage")
	'if all went well, shortUrl will contain the full short URL created for our link
	Dim nShortUrl As XmlNode = objXML.SelectSingleNode("//shortUrl")

	'if we didn't get an errorCode value of 0, there was a problem; report the user-friendly message
	'on success, report the short URL for our resource
	If nErrorCode.InnerText <> "0" Then
		lblStatus.Text = "Error returned. Code: " & nErrorCode.InnerText & "; Message: " & nErrorMsg.InnerText
	Else
		lblStatus.Text = nShortUrl.InnerText
	End If
End Sub

Note the extensive similarity in shortening URLs with the bit.ly API to posting status updates with the Twitter API. That’s one of the many benefits of REST; the basic approach to retrieving, adding, updating and deleting data tends to be similar for all RESTful applications.

At some point, I plan to explain, in plain English, how REST works. It’s also worth noting that neither the Twitter nor bit.ly APIs are truly RESTful; that’s something I will explain in a future post.

A few notes about the bit.ly API and the code above:

  • This code requires the System.Net, System.IO and System.Xml namespaces. Chances are, if you built your Web application in Visual Studio, these namespaces are already referenced in your web.config file.
  • This code should work for ASP.NET versions 1.1 forward.
  • As the comment on Line 5 states, by default the bit.ly API will return its response as JSON. In the case of server-side programming, it’s easier to work with XML, so we need to explicitly instruct bit.ly to respond with XML.
  • I use a StringBuilder to form the request URL in order to be very explicit about the components of the URL, especially in terms of from where its parts are drawn and what each part does. This is another case of choosing transparency over elegance. You can replace the StringBuilder with string concatenation if you want.
  • To authenticate yourself in the bit.ly API, you can either send your bit.ly username and your API key as querystring variables, or use basic HTTP authentication. I am using the querystring variables method for simplicity’s sake, but it is rather less secure than basic authentication. This would be more of a concern if we were using an AJAX solution that exposed both your username and API key directly to end users.
  • Your bit.ly API key can be found on your bit.ly account page (log in to the Web site and click the Account link in the upper right-hand corner). Do not send your bit.ly password when you attempt to authenticate via querystring; use your API key only. Don’t replace apiKey with password, don’t substitute your password for the apiKey value, etc.
  • Your long URL must be a fully qualified URL. For example, don’t send server.com/page.html, send http://www.server.com/page.html.
  • We need not set any content for our request; we’ll be sending everything we need to send via the header. Thus, we set the ContentLength property for the request to 0, so that bit.ly doesn’t sit around waiting for data that’s never coming.
  • In order to get back from bit.ly the shortened URL it creates, we need to capture the XML response it sends. In my previous tutorial about the Twitter API, my code pretty much ignored the returned XML, because I simply assume the tweet went through. If you want to take a more pessimistic view of tweeting via the API, you can use the same methods I use here to access return values.
  • Thankfully, when bit.ly responds via XML to a shorten request, it always sends the nodes errorCode, errorMessage and shortUrl, regardless of the success of the request. Even more fortunate for us, there are only one of each of those nodes in every response. Therefore, we can use a combination of the the SelectSingleNode method, and the XPath selector //{node} (where {node} is the local name of the node), to get the values contained in errorCode, errorMessage and shortUrl.
  • Once again, I am using a label with the ID of lblStatus to report the results of the request. You can change this code however you like to handle success or failure.
  • This time, I’m not using a try-catch block to see if there are problems with the request or response. You may find this code throws exceptions if you are sending bad querystring parameters, especially malformed longUrl parameters (for example, you send an incomplete URL as your longUrl value.) You can add a try-catch block if you want.

If you have a user name of foobar, an API key of R_bar123456abcd90876poi, and a long URL of http://www.helloworld.com, you would call this subroutine out-of-the box thus:

BitlyIt("foobar", "R_bar123456abcd90876poi", "http://www.helloworld.com")

The same methodologies I discussed in the Twitter API post for using a button, letting people shorten URLs with their own accounts via a form, storing your bit.ly account information in your web.config file, etc. all can be applied to this solution; I’ll trust that most people can adapt those methodologies to this code, but if there are requests to clarify, I will visit those tasks in the comments.

Finally, like the Twitter API, the bit.ly API has a rate limit; in this case, no more than five simultaneous connections.

In theory, your server should disconnect from the bit.ly API servers immediately after making its shorten request, but it is possible your server’s requests will be kept alive for whatever reason, and the ASP.NET garbage collector won’t come by quickly enough to clean them up. That’s highly improbable, so rate limits shouldn’t be an issue here.

Even so, again I am not posting a working demo. I have tested this code and it does work.

I distribute code under the GNU GPL. See Copyright & Attribution for details.

8 thoughts on “Shortening URLs With The bit.ly API Via ASP.NET

  1. Raghu

    Hi Doug,its a very nice article..My question is how can we get the “short_url_length”,”short_url_length_https” values through code?

  2. Raghu

    Hi Doug..Thanks for your reply,Twitter Documentation has specified the “short_url_length” as 22..is it possible to retrieve the short_url_length value specified by twitter into our application through property?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current ye@r *