Recently, I had a case where an ASP.NET page displayed the user's URL in a side column. This worked fine except that I found some users had very long URLs, which didn't look right.
It occurred to me that I could simple truncate the visible URL while still keeping the underlying link the same. However, when I truncated the URL by trimming excess characters, I realized it could be done more intelligently.
For example, consider the URL http://www.domain.com/here/is/one/long/url/page.aspx. If I wanted to keep it within 40 characters, I could trim it to http://www.domain.com/here/is/one/long/u. The problem is that this abbreviation could be more informative. For example, is it a directory or a page? And, if it's a page, what kind? And what exactly does the "u" at the end stand for?
Wouldn't it be a little better if I instead abbreviated this URL to http://www.domain.com/.../url/page.apsx? We've lost a few characters due to the three dots that show information is missing. But we can still see the domain, and the page name and type.
The code is Listing 1 abbreviates a URL is this way. The UrlHelper
class contains just a single, static
method, LimitLength()
. This method takes a URL string
and a maximum length arguments, and attempts to abbreviate the URL so that it will fit within the specified number of characters as described above.
public class UrlHelper
{
public static char[] Delimiters = { '/', '\\' };
public static string LimitLength(string url, int maxLength)
{
if (maxLength < 5)
maxLength = 5;
if (url.Length > maxLength)
{
int i = url.IndexOfAny(new char[] { ':', '.' });
if (i >= 0 && url[i] == ':')
url = url.Remove(0, i + 1);
i = 0;
while (url.Length > 0 && (url[i] == Delimiters[0]
|| url[0] == Delimiters[1]))
i++;
if (i > 0)
url = url.Remove(0, i);
if (url.Length > maxLength && (url.EndsWith("/") || url.EndsWith("\\")))
url = url.Remove(url.Length - 1);
if (url.Length > maxLength)
{
i = url.IndexOfAny(Delimiters);
if (i >= 0)
{
string first = url.Substring(0, i + 1);
string last = url.Substring(i);
bool trimmed = false;
do
{
i = last.IndexOfAny(Delimiters, 1);
if (i < 0 || i >= (last.Length - 1))
break;
last = last.Substring(i);
trimmed = true;
} while ((first.Length + 3 + last.Length) > maxLength);
if (trimmed)
url = String.Format("{0}...{1}", first, last);
}
}
}
return url;
}
}
Listing 1: UrlHelper class.
If the specified maximum length is less than five, LimitLength()
simply changes it to five as there is no point in attempting to shorten a URL to less than the length of the protocol (http://).
That's all there is to it. I hope some of you find this code helpful.