Brevity is the soul of wit [A free, easy, custom URL shortening solution for ASP.NET!]
I tend to write pretty long blog post titles.
There, I said it.
That's the first step, right? Admitting the problem? Except I don't usually think it's a problem...
It probably doesn't. But I wanted one anyway. In particular, I wanted something ridiculously simple to manage that I had complete control over and that didn't depend on how my web site host configured their server. I wanted to be sure I could use human-readable aliases and never need to worry about namespace collisions (a problem with existing services because all the good names have been taken). Besides, I don't see the point in relying on someone else (or some other web site) to do something I can do for myself pretty easily.
So as long as I'm writing my own URL shortener, I might as well give it a special power or something, right? Well, one thing that seemed pretty useful (to me and you) was an easy way to list all the supported aliases. Therefore, when you navigate to the root of the redirect namespace on my web site, that's just what you'll get:
Now, when I want to point to a blog or sample of mine, instead of linking to it like this:
I can link to it like this:
What's more, because these redirects are of the 302/Found variety, I can update where they go when new content becomes available without having to change any existing content. This is something I've wanted for my links post(s) ever since I posted the first version! Problem solved: from now on, the DVLinks
alias will always take you to my most recent post of Data Visualization links.
Some of the aliases above use MixedCase
and some use ALLCAPS
- there's actually meaning behind that. When I create an alias I intend to be widely useful and expect to use more than once, I'll use mixed case like I did with DVLinks
. But when I'm creating an alias just so I can post it to Twitter, I'll use all caps like I did for TWITTER
. This way, it's easy to browse my list of aliases and pick out the particularly interesting ones.
Here's the complete code for the IHttpModule-based URL shortener I wrote last night. It's standard ASP.NET and doesn't use any .NET 3.5 features, so it should work fine on pretty much any ASP.NET server.
public class UrlShortener : IHttpModule { /// <summary> /// The prefix (directory/namespace) for all redirect requests. /// </summary> private const string RedirectPrefix = "~/r/"; /// <summary> /// Maintains a mapping from alias to Uri for all redirect entries. /// </summary> private IDictionary<string, Uri> _aliases = new SortedDictionary<string, Uri>(StringComparer.OrdinalIgnoreCase); /// <summary> /// Initializes the IHttpModule instance. /// </summary> /// <param name="context">HttpApplication instance.</param> public void Init(HttpApplication context) { // Populate the alias mappings AddAlias("ChartBuilder", "https://dlaa.me/Samples/ChartBuilder/"); AddAlias("DVLinks", "http://blogs.msdn.com/delay/archive/2009/07/19/my-new-home-page-enhanced-updated-collection-of-great-silverlight-wpf-data-visualization-resources.aspx"); AddAlias("SLHash", "https://dlaa.me/Samples/ComputeFileHashes/"); AddAlias("TWITTER", "http://blogs.msdn.com/delay/archive/2009/10/13/if-all-my-friends-jumped-off-a-bridge-apparently-i-would-too-just-created-a-twitter-account-davidans.aspx"); context.BeginRequest += new EventHandler(HttpApplication_BeginRequest); } /// <summary> /// Adds an alias/Uri pair and validates it. /// </summary> /// <param name="alias">Alias to add.</param> /// <param name="uri">Uri to associate with the alias.</param> private void AddAlias(string alias, string uri) { // Validate the URI when adding it _aliases.Add(alias, new Uri(uri, UriKind.Absolute)); } /// <summary> /// Handles the HttpApplication's BeginRequest event. /// </summary> /// <param name="source">HttpApplication source.</param> /// <param name="e">Event arguments.</param> private void HttpApplication_BeginRequest(object source, EventArgs e) { // Check if the request is a redirect attempt HttpApplication context = (HttpApplication)source; string requestPath = context.Request.AppRelativeCurrentExecutionFilePath; if (requestPath.StartsWith(RedirectPrefix, StringComparison.OrdinalIgnoreCase)) { // Extract the alias string alias = requestPath.Substring(RedirectPrefix.Length); if (_aliases.ContainsKey(alias)) { // Known alias; redirect the user there context.Response.Redirect(_aliases[alias].ToString()); } else { // Invalid alias; write a simple list of all known aliases using (HtmlTextWriter writer = new HtmlTextWriter(context.Response.Output, "")) { writer.RenderBeginTag(HtmlTextWriterTag.Html); writer.RenderBeginTag(HtmlTextWriterTag.Head); writer.RenderBeginTag(HtmlTextWriterTag.Title); writer.Write("Supported Aliases"); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Body); foreach (string key in _aliases.Keys) { writer.AddAttribute(HtmlTextWriterAttribute.Href, _aliases[key].ToString()); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write(key); writer.RenderEndTag(); writer.WriteBreak(); writer.WriteLine(); } writer.RenderEndTag(); writer.RenderEndTag(); } context.Response.End(); } } } /// <summary> /// Disposes of resources. /// </summary> public void Dispose() { } }
To enable this URL shortener for IIS 7, just save the code above to a .CS file, put that file in the App_Code
directory at the root of your web site, and register it in web.config
with something like the following:
<?xml version="1.0"?> <configuration> <system.webServer> <modules> <add name="UrlShortener" type="UrlShortener"/> </modules> </system.webServer> </configuration>
(For IIS 6, you'll need to change system.webServer
to system.web
and modules
to httpModules
- otherwise it's just the same.)