Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Gravatar Implementation


:P
On this page:

I took a little bit of time today to make a few minor changes to the blog here and added some enhancements to the comments section here. One of the additions is support for Gravatars which is a very simple REST based mechanism that lets you show an avatar image. Gravatar is implemented by quite a few sites these days (SubText, DasBlog and Community Server all support it for example), so if you access any of these sites you can get your image shown on those sites.

This is nothing new really (especially given that the above engines have had it for a while), but I thought it makes a nice change of pace on this blog to talk about something that's straight forward for a change <g>...

Gravatar is a very simple mechanism: The user signs up with a site with his or her email addresss and uploads an image. The image is resized into a square and displayed as a gravatar of up to 80 x 80 pixels (determined by the link). Gravatar is purely REST based and works by the calling site embedding an image link that contains an encrypted URL querystring that references the image URL. It's all very simple and can be accomplished literally with a few lines of code.

For fun here's how it works. First there's the Gravatar implementation the details of which you can find on the Gravatar site. The concept is basically that you embed an image URL into your site and the image is then served by Gravatar. The image is referenced via an MD5 hash and HexBin encoding of the email address. Here's my quick and dirty implementation:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
 
namespace Westwind.Weblog
{
    /// <summary>
    /// Implements the Gravatar API for retrieving a Gravatar image to display
    /// </summary>
    public class Gravatar
    {
        public const string GravatarBaseUrl = "http://www.gravatar.com/avatar.php?";
 
        /// <summary>
        /// Returns a Gravatar URL only
        /// </summary>
        /// <param name="Email"></param>
        /// <param name="Size"></param>
        /// <param name="Rating"></param>
        public static string GetGravatarLink(string Email, int Size, string Rating, string DefaultImageUrl)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] Hash = md5.ComputeHash(Encoding.ASCII.GetBytes(Email));
 
            StringBuilder sb = new System.Text.StringBuilder();
            for (int x = 0; x < Hash.Length; x++)
            {
                sb.Append(Hash[x].ToString("x2"));
            }
 
            if (!string.IsNullOrEmpty(DefaultImageUrl))
                DefaultImageUrl = "&default=" + DefaultImageUrl;
            else
                DefaultImageUrl = "";
 
            return string.Format("{0}?gravatar_id={1}&size={2}&rating={3}{4}",
                                   Gravatar.GravatarBaseUrl, sb.ToString(), Size, Rating, DefaultImageUrl);
        }
 
        /// <summary>
        /// Returns a Gravatar Image Tag that can be directly embedded into
        /// an HTML document.
        /// </summary>
        /// <param name="Email"></param>
        /// <param name="Size"></param>
        /// <param name="Rating"></param>
        /// <param name="ExtraImageAtributes"></param>
        /// <returns></returns>
        public static string GetGravatarImage(string Email, int Size, string Rating,                                               
                                              string ExtraImageAttributes,string DefaultImageUrl)
        {
            string Url = GetGravatarLink(Email, Size, Rating, DefaultImageUrl);
            return string.Format("<img src='{0}' {1}>",Url,ExtraImageAttributes,DefaultImageUrl);
        }
 
 
        /// <summary>
        /// Return a full Html img tag for a GravatarBaseUrl
        /// </summary>
        /// <param name="Email"></param>
        /// <param name="ExtraImageAttributes"></param>
        /// <returns></returns>
        public static string GetGravatarImage(string Email, string ExtraImageAttributes)
        {
            return GetGravatarImage(Email, 80, "G", ExtraImageAttributes, string.Empty);
        }
    }
}

Nothing complicated here. MD5 encoding is built into .NET and the HexBin conversion is easy to do. HexBin is basically just a hex representation of each character by converting the character into its two character hex representation.

There are two static methods - one that generates only the URL and one that generates the full image which is likely the most common scenario. A couple of things that I like to do with the Gravatar. First off if the user didn't leave an email address I prefer not to show an image and if the entry happens to be not a blog entry but trackback too it shouldn't actually show a gravatar.

So here's how it gets called off a repeater in the page:

    <asp:Repeater runat="server" ID="repFeedback" OnItemCommand="repFeedBack_ItemCommand" EnableViewState="false">
       <ItemTemplate>
            <div class="<%# (string) Eval("Author") == App.Configuration.WebLogAuthor ? "comment commentauthor" : "comment" %>" >
            <%# WebUtils.GravatarLink( Container.DataItem as System.Data.DataRowView ) %>
            <b><%# Eval("Title")  %></b><br />
            <small> by
                <%# string.IsNullOrEmpty( Eval("Url") as string) ? Eval("Author") as string : wwUtils.Href( Eval("Author") as string,Eval("Url") as string,"_WebLog",null) %> &nbsp;&nbsp; <%# WebUtils.WebLogDateString( (DateTime) Eval("Entered"),true ) %> 
                <%# string.IsNullOrEmpty( Eval("Body") as string ) ?  "" : "<br /><br />" + (Eval("Body") as string) %> 
                <asp:LinkButton runat="server" ID="lnkRemoveComment" visible="<%# this.IsAdmin %>"
                                CommandName="RemoveComment" CommandArgument='<%# Eval("pk") %>'><br />Remove Comment</asp:LinkButton>
            </small>
            </div>
        </ItemTemplate>
    </asp:Repeater>

 

Note rather than directly linking the Gravatar link it calls off into a static utility method (primarily because this link is used in several places). The method needs to check a few things so rather than pass a slew of Eval() parameters I instead pass the Dataitem as whole and so give the method access to all the fields from this query.

/// <summary>
/// Generate a gravatar link
/// </summary>
/// <param name="Email"></param>
/// <returns></returns>
public static string GravatarLink(DataRowView Row)
{
    // *** Only add gravatar to comments
    if ((int)Row["EntryType"] != 3)
        return "";
 
    string Email = (string)Row["Email"];
    if (string.IsNullOrEmpty(Email))
        return "";
 
    return Gravatar.GetGravatarImage(Email,"style='opacity:.75;filter:alpha(opacity=\"75\");' align='right' hspace='5'");
}

In general I'm a big fan of calling page level methods or (in this case) generic static methods if more than one or two operations need to be set because of the hideousnous that otherwise ensues in the ASP.NET HTML markup. Compare this simple method eval even to the relatively simple conditional Author logic above trying to figure out which Css Class to display on the div for example. <s>

Anyway. After playing around with new technology in R & D modes for the last few weeks, sometimes it's nice to come back to some simple code that produces results in just a few minutes of work instead of days <s>...

Posted in ASP.NET  

The Voices of Reason


 

Haacked
May 17, 2007

# re: Gravatar Implementation

Now you just need to make an Identicon the default image for the gravatar for users who don't have a gravatar, like I did on my blog using the <a href="http://haacked.com/archive/2007/03/19/identicon-handler-for-.net-on-codeplex.aspx">Identicon Handler</a>. ;)

Keith Elder
May 17, 2007

# re: Gravatar Implementation

The other thing that anyone doing this should note is the MD5 hash you send Gravatar.com is case sensitive, at least it is right now. It needs to be only lower case.

Josh Stodola
June 05, 2007

# re: Gravatar Implementation

It looks tacky when the comment DIV is smaller than the gravatar image itself (less than 80 pixels in height). Perhaps overflow-y:hidden can correct this (in IE, at least)?

Rick Strahl
June 05, 2007

# re: Gravatar Implementation

Josh, yeah I know, not too happy about that, but I couldn't get this to work consistently. I'm using min-height which works in Mozilla but I think I didn't specify the height quite big enough. It's off by a few pixels.

Josh Stodola
June 05, 2007

# re: Gravatar Implementation

Yeah, its no big deal. It's just another one of those things you toss up and after wasting enough time seeking a solution, a point to say "screw it" is reached. It's only on the one-liner comments, anyways.

Well, I got curious. I read your point about using min-height and was kind of baffled to hear you say it only works in Mozilla, because I just went through an IE height battle not too long ago. After viewing the page source, it appears the min-height is only being applied to *your* comments (author comments). That completely explains why your gravatar on this page completely shows, but Phil Haack's is hitting the edge. It being off by a few pixels is likely related to the padding of the comment box. Im not being picky by any means, and Im not really a perfectionist myself. The geek in me simply forced me to investigate <g>

Hope this helps...

Me
June 08, 2007

# re: Gravatar Implementation


lilie
August 17, 2007

# re: Gravatar Implementation

Hello
I am bad because gravater don't charge in my site. But I implement ou code
and when I compare the url of the image there are same. :(

lilie
August 17, 2007

# re: Gravatar Implementation

Hello
I am bad because gravater don't charge in my site. But I implement ou code
and when I compare the url of the image there are same. :(

Sorry I restest with the good email

Paul
August 28, 2007

# re: Gravatar Implementation

Very cool stuff.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024