Archive for September 2009
Here is a quick little URL Helper extension method to add Gravatar images/photos/avatars to your page:
public static string GravatarUrl(this UrlHelper url, string email, int size){string imageUrl = ConfigurationManager.AppSettings["DefaultGravatar"];if (imageUrl.StartsWith("~/")){imageUrl = url.Absolute(imageUrl);}if (string.IsNullOrEmpty(email)){return imageUrl;}string md5 = email.ToLowerInvariant().MD5();return string.Format("http://www.gravatar.com/avatar/{0}.jpg?d={1}&s={2}&r=g",md5.ToLowerInvariant(),url.Encode(imageUrl),size);}public static string GravatarUrl(this UrlHelper url, string email){return url.GravatarUrl(email, 32);}
It uses another custom URL Helper extension method Absolute to generate an absolute URL to a default image (based on an application relative url).
The Absolute extension method is similar to the ActionAbsolute method I posted earlier:
public static string Absolute(this UrlHelper url, string contentUrl){return new Uri(GetBaseUrl(url), url.Content(contentUrl)).AbsoluteUri;}
And it also used the MD5 extension method from yesterdays post.
A nifty little extension method that generated the MD5/SHA-1 hash of a string. These methods are a continuation of my previous post:
public static string MD5(this string value){System.Security.Cryptography.MD5 algorithm =System.Security.Cryptography.MD5.Create();byte[] data = Encoding.ASCII.GetBytes(value);data = algorithm.ComputeHash(data);string md5 = "";for (int i = 0; i < data.Length; i++){md5 += data[i].ToString("x2").ToLower();}return md5;}
Just substitute MD5 for SHA1, SHA256, SHA384, SHA512 or RIPEMD160 which ever hash algorithm fits your needs.
Extension Methods · hash · md5 · Secure Hash
Showing an absolute date on a webpage, e.g. January 22, 2009 13:01, is of course a very normal way to do it, apart from various different date formats, it is easily read and consumed. However if the date is shown in a context where the absolute date is of little importance, but it is more important to know if it was a long time ago, just now or maybe just in a couple of minutes, a relative and more descriptive method is better.
For example the date mentioned above might be described as “8 months ago”. Just by giving it a quick glance you get an idea about when this event occurred.
For this here are a couple of extension methods that generate this descriptive text based on a given time:
public static string ToRelativeTime(this DateTime from){DateTime now = DateTime.Now;return from.ToRelativeTime(now);}public static string ToRelativeTime(this DateTime from, bool usePreAndSuffix){DateTime now = DateTime.Now;return from.ToRelativeTime(now, usePreAndSuffix);}public static string ToRelativeTime(this DateTime from, DateTime to){return from.ToRelativeTime(to, true);}public static string ToRelativeTime(this DateTime from, DateTime to, bool usePreAndSuffix){string prefix = usePreAndSuffix && (from > to) ? "in " : string.Empty;string suffix = !usePreAndSuffix || (from > to) ? string.Empty : " ago";// is more than 1 year?if (from > to){DateTime d = from;from = to;to = d;}int years = to.Year - from.Year;if ((to.Month < from.Month) || ((to.Month == from.Month) && (to.Day < from.Day))){years--;}if (years > 1){return string.Format("{0}{1} years{2}", prefix, years, suffix);}else if (years == 1){return string.Format("{0}1 year{1}", prefix, suffix);}// less than 1 year, is more than 1 month?int months = to.Month - from.Month;if (months < 0){months += 12;}if ((to.Day < from.Day) || ((to.Day == from.Day) && (to.TimeOfDay < from.TimeOfDay))){months--;}if (months > 1){return string.Format("{0}{1} months{2}", prefix, months, suffix);}else if (months == 1){return string.Format("{0}1 month{1}", prefix, suffix);}// less than 1 month, is more than 1 day/week?TimeSpan diff = to - from;if (diff.Days > 7){return string.Format("{0}{1} weeks{2}", prefix, diff.Days / 7, suffix);}else if (diff.Days > 1){return string.Format("{0}{1} days{2}", prefix, diff.Days, suffix);}else if (diff.Days == 1){return string.Format("{0}1 day{1}", prefix, suffix);}// less than 1 day, is more than 1 hour?if (diff.Hours > 1){return string.Format("{0}{1} hours{2}", prefix, diff.Hours, suffix);}else if (diff.Hours == 1){return string.Format("{0}1 hour{1}", prefix, suffix);}// less than 1 hour, is more than 1 minute?if (diff.Minutes > 1){return string.Format("{0}{1} minutes{2}", prefix, diff.Minutes, suffix);}else if (diff.Minutes == 1){return string.Format("{0}1 minute{1}", prefix, suffix);}// less than 1 minuteif (diff.Seconds == 1){return string.Format("{0}1 second{1}", prefix, suffix);}else if (diff.Seconds < 1){return string.Format("{0}less than 1 second{1}", prefix, suffix);}return string.Format("{0}{1} seconds{2}", prefix, diff.Seconds, suffix);}
This can of course be optimized for localization etc.
