SharePoint: Creating HttpHandler for user profile images

I have custom authentication and user profiles solution where user profiles are stored in list. This list is directly accessible only to administrators. Users can register to site and modify their profiles through special pages that run profile operations under elevated privileges. Users have three versions of their avatar: 64x64, 32x32 and 16x16. These avatars are saved as user profile attachments when user uploads his or her avatar. Because avatars are used at almost every page in portal I wrote IHttpHandler that provides avatars based on user profile ID.

Here is shortened draft version of my code (I removed some complex guard checks that use custom extensions methods for SharePoint objects).


public class ProfileImageHandler : IHttpHandler

{

    public bool IsReusable

    {

        get { return true; }

    }

 

    public void ProcessRequest(HttpContext context)

    {

        var request = context.Request;

        var response = context.Response;

 

        var idString = request.QueryString["id"];

        var sizeString = request.QueryString["size"];

        var id = 0;

 

        int.TryParse(idString, out id);

 

        var siteId = SPContext.Current.Site.ID;

        var sec = new SPSecurity.CodeToRunElevated(delegate()

                {

                    using (var site = new SPSite(siteId))

                    {

                        using (var web = site.OpenWeb())

                        {

                            if (id == 0)

                            {

                                OutputDefaultImage(web, response);

                                response.End();

                                return;

                            }

 

                            var list = web.Lists["ProfileList"];

                            var item = list.GetItemById(id);

 

                            sizeString = sizeString + "x" + sizeString;

                            foreach (string fileName in item.Attachments)

                            {

                                if (!fileName.Contains(sizeString))

                                    continue;

                                var fileUrl = item.Attachments.UrlPrefix + fileName;

                                var file = web.GetFile(fileUrl);

 

                                var stream = file.OpenBinaryStream();

                                var bytes = new byte[stream.Length];

 

                                stream.Read(bytes, 0, bytes.Length);

                                response.Clear();

                                response.ContentType = "image/png";

                                response.BinaryWrite(bytes);

 

                                stream.Dispose();

                                response.End();

                            }

                        }

                    }

                }

            );

        SPSecurity.RunWithElevatedPrivileges(sec);

    }

 

    private void OutputDefaultImage(SPWeb web, HttpResponse response)

    {

        var defaultFileUrl = "/Style Library/portal/images/user.gif";

        var defaultFile = web.GetFile(defaultFileUrl);

        var defaultFileStream = defaultFile.OpenBinaryStream();

        var defaultBytes = new byte[defaultFileStream.Length];

 

        defaultFileStream.Read(defaultBytes, 0, defaultBytes.Length);

        response.Clear();

        response.ContentType = "image/png";

        response.BinaryWrite(defaultBytes);

 

        defaultFileStream.Dispose();

    }

}


The code here works as follows. It retrieves user profile by id and checks if profile has image with given width and height. Avatars in this system are squares so I need to know only size of one side. If user profile doesn’t have attachment that contains size x size (by example “32x32”) in its name then default profile image is returned.

Let’s suppose we have user profile (id = 176) and we want 32x32 size avatar for this profile. Also let’s assume there is userimagehandler.ashx file in the folder portalhandlers. We can ask 32x32 avatar by using the following request.

/_layouts/portalhandlers/userimagehandler.ashx?size=32&id=176

As URL for each avatar size is unique for each profile then it is also possible to cache avatars so there is no need to read them from content database per every request.


kick it on DotNetKicks.com pimp it Progg it 顶 Shout it
vote it on WebDevVote.com Vote it

6 Comments

  • I would strongly consider adding some 304 plumbing so the images are cached in the browser...

    http://weblogs.asp.net/jeff/archive/2009/07/01/304-your-images-from-a-database.aspx

  • Hi,
    Thanks for your useful article!
    I also use httphandler for displaying images in my program. One image can be displayed. But when there are multiple images, only one displays; the cross sign displays instead of others. However, after right clicking on the cross and choose display image, it becomes visible.

    More details...

    My program is a personel search web part and it gets personel images from db and displays on personel user control. The control uses HttpHandler for image source.

    But as I have said, when multiple images are wanted to listed, there is the above problem.

    Any idea?
    Thanks.
    Thanks.

  • Open the URL of image that is not shown in your browser and see what is the error you get. You may also check errors out from SharePoint logs.

  • Hi

    I have a HTTPHandler where the "SPContext" is NOT available.
    Any ideas or guidlines on how to get access to SPContext from HTTPHandler?

    Thanks
    Karina

  • Thanks for question, Karina!

    Is your application usual ASP.NET web application or is it SharePoint application?

  • Okay, can you show me the definition of your HTTP handler?

    public class MyHandler : ???? <- what you have here?
    {
    }

Comments have been disabled for this content.