Tuesday, March 22, 2011

Gravatar Helpers | ASP.NET MVC

Update: 2011-04-26 Changed the methods from returning string to returning MvcHtmlString (silly me) and created a few more overloads to assign a title attribute.

Was looking for a helper that I'd seen previously. I still haven't found it, but noticed this post with Gravatar helpers.

I've adjusted it in the following ways:
  • The code didn't trim or lowercase the email address before hashing, so I changed that
  • I added an overload which takes an enum for selecting the default image. 
  • The Url for the default image was not being Url encoded. This is fine if you are using one of the defaults that they provide, but might not work if you pass a Url to an image in.
  • There are several more overloads
  • Generally made more of a mess :oD
Some of these changed just help to ensure that there are no problems when getting the Gravatar, some are just niceties for me which are probably a little clearer to read, but not really necessary considering that you would generally call these a total of maybe 1 or 2 places in an application.

Hope this is useful to someone.
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;

namespace Catechize.Helpers
{
    public enum GravatarDefault
    {
        FileNotFound,
        MysteryMan,
        Identicon,
        MonsterID,
        Wavatar,
        Retro
    }

    // Kudos to Rob Connery http://blog.wekeroad.com/2010/01/20/my-favorite-helpers-for-aspnet-mvc
    public static class GravatarHelpers
    {
        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email)
        {
            var url = GetGravatarUrl(helper, CleanupEmail(email), 40, GetDefaultGravatarString(GravatarDefault.MysteryMan));
            return MvcHtmlString.Create(ConstructImgTag(url));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, string title) {
            var url = GetGravatarUrl(helper, CleanupEmail(email), 40, GetDefaultGravatarString(GravatarDefault.MysteryMan));
            return MvcHtmlString.Create(ConstructImgTag(url, title));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, int size)
        {
            var url = GetGravatarUrl(helper, CleanupEmail(email), size, GetDefaultGravatarString(GravatarDefault.MysteryMan));
            return MvcHtmlString.Create(ConstructImgTag(url));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, string title, int size)
        {
            var url = GetGravatarUrl(helper, CleanupEmail(email), size, GetDefaultGravatarString(GravatarDefault.MysteryMan));
            return MvcHtmlString.Create(ConstructImgTag(url, title));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, int size, string defaultImageUrl)
        {
            var url = GetGravatarUrl(helper, CleanupEmail(email), size, UrlEncode(helper, defaultImageUrl));
            return MvcHtmlString.Create(ConstructImgTag(url));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, string title, int size, string defaultImageUrl)
        {
            var url = GetGravatarUrl(helper, CleanupEmail(email), size, UrlEncode(helper, defaultImageUrl));
            return MvcHtmlString.Create(ConstructImgTag(url, title));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, int size, GravatarDefault defaultImage)
        {
            var mode = GetDefaultGravatarString(defaultImage);

            var url = GetGravatarUrl(helper, CleanupEmail(email), size, mode);
            return MvcHtmlString.Create(ConstructImgTag(url));
        }

        public static MvcHtmlString Gravatar(this HtmlHelper helper, string email, string title, int size, GravatarDefault defaultImage)
        {
            var mode = GetDefaultGravatarString(defaultImage);

            var url = GetGravatarUrl(helper, CleanupEmail(email), size, mode);
            return MvcHtmlString.Create(ConstructImgTag(url, title));
        }

        public static string GetDefaultGravatarString(GravatarDefault defaultGravatar) {
            var mode = String.Empty;
            switch (defaultGravatar)
            {
                case GravatarDefault.FileNotFound:
                    mode = "404";
                    break;
                case GravatarDefault.Identicon:
                    mode = "identicon";
                    break;
                case GravatarDefault.MysteryMan:
                    mode = "mm";
                    break;
                case GravatarDefault.MonsterID:
                    mode = "monsterid";
                    break;
                case GravatarDefault.Wavatar:
                    mode = "wavatar";
                    break;
                case GravatarDefault.Retro:
                    mode = "retro";
                    break;
                default:
                    mode = "mm";
                    break;
            }
            return mode;
        }


        private static string ConstructImgTag(string src, string title = "Gravatar")
        {
            var result = "\"Gravatar\"";
            return String.Format(result, src, title);
        }

        static string GetGravatarUrl(HtmlHelper helper, string email, int size, string defaultImage)
        {
            string result = "http://www.gravatar.com/avatar/{0}?s={1}&r=PG";
            string emailMD5 = EncryptMD5(CleanupEmail(email));

            result = (string.Format(result,
                        EncryptMD5(email), size.ToString()));

            if (false == String.IsNullOrEmpty(defaultImage))
                result += "&d=" + defaultImage;
        
            return result;
        }

        private static string UrlEncode(HtmlHelper helper, string url)
        {
            var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
            return urlHelper.Encode(url);
        }

        private static string CleanupEmail(string email)
        {
            email = email.Trim();
            email = email.ToLower();

            return email;
        }

        private static string EncryptMD5(string value)
        {
            byte[] bytes;

            using (var md5 = MD5.Create())
            {
                bytes = Encoding.ASCII.GetBytes(value);
                bytes = md5.ComputeHash(bytes);
            }

            return String.Concat(bytes.Select(t => t.ToString("x2")));
        }
    }
}

No comments:

Post a Comment