Friday 23 March 2012

Display Flickr photos on .Net MVC web page

Functional Brief
I am working on a website for the Drumshanbo An Tostal Festival and one of the requirements was to show photos on the web site that the festival committee has stored on Flickr. I didn't want to just copy and paste a bunch of HTML onto the web page. I found that the existing web site they had was slow to load all of the Flickr images. What I really wanted to do was show a few photos and then provide a link to the full library of photos on Flickr.

Flickr allows you to add a set of photos as a PhotoSet. I wanted to get the last 5 PhotoSets from Flickr and display 7 photos from each set on the web page. The reason why I wanted 5 PhotoSets and 7 photos as that amount of photos fit in well with the size of the page space I wanted to fill.


What did I do next?
I started doing some research to see if there were any .Net projects already created that integrated with the Flickr API. After a bit of searching I came across this library on codeplex: http://flickrnet.codeplex.com/

I downloaded the libraries and added the reference to the FlickrNet.dll to my project. So now that I had a library I needed to add some code to my page to use it.

Thankfully the web provided me with some further quick start information in the form of this article on CodeProject: http://www.codeproject.com/Articles/127155/A-Simple-ASP-NET-Flickr-Application

And lastly...
Now all I needed to do was get this working in my MVC project.

Steps I took to get this to work:
1. Added a new folder to my AnTostalFestival.WebUI project called Utitilities
2. Added a new class to the Utilities folder and called it FlickrBLL.cs
3. Using the code from the codeproject article I retyped the class. I don't like to copy and paste as you can never get enough practice typing out code. Repitition is the mother of all skill!
3. At this point I realised why I need a new app key so I applied for a new App key on Flickr. I got one instantly since I wasn't doing a commercial site. Flickr explains why this is relevant.
4. I updated my web.config file with the keys
5. I then added the code to my view to output the Flickr photos

I am not going to explain in any further detail steps 1-4 above as they are covered in the other articles. I am going to explain Step 5 since this is kinda the reason why I am posting this in the first place.

Step 5 - Adding the code or The Good Bits


@using AntostalFestival.WebUI.Utilities
@{
    FlickrBLL flickrPhotos = new FlickrBLL();
    var flickrUserName = "50568405@N06"//this is the username of the flickrUser that I want to get the photosets from
    var flickrPhotosetPageNumber = 1; //if you only have one page of photo sets on Flickr then just leave this at 1
    var numberOfPhotosetsToReturn = 6;
    var photoSetList = FlickrBLL.GetPhotoSetsByUser(flickrUserName, flickrPhotosetPageNumber, numberOfPhotosetsToReturn);
}
<div id="subpagecontent" class="subpagecontent">
    <span class="subpageinformationblocks">Archive: Previous festivals</span>
    </br>
    @foreach (var photoSetID in photoSetList)
    {
        <table width="550px">
            <tr>
                <td><h5>@photoSetID.Title.ToString():</h5></td>
                <td class="flickrLink"><a target="_new" class="flickrLink" href="@photoSetID.Url.ToString()">View full photoset on Flickr</a></td>
            </tr>
        </table>
       
        <br />
        var photos = FlickrBLL.GetPagedSet(photoSetID.PhotosetId.ToString(), 7, 0);
        foreach (var photo in photos)
        {
            <img src="@photo.SquareThumbnailUrl.ToString()" />
        }          
    }
</div>

The Flickr.Net library allows you to request details of photosets from your photoset pages in Flickr. I am not sure what the page photoset page size is on Flickr but I think it's 10 photosets per page before you get the paging links at the bottom of the screen. Here is an example of a photoset page in Flickr:



As you can see this is the first and only page of photosets and there are 6 photosets on page 1.

But what might you notice here now?
You might have noticed that the code from the code project page does not allow you to pass in the page number and photo set number. Well you'd be right and so therefore I modified the PhotoSetCollection method my FlickrBLL class, in the Flickr.Bll file, to allow me to pass in the page number and photoset number.

So here is the updated PhotosetCollection method where you can see that I have added the photoSetPage and setsPerPage parameters to the method signature.


        [DataObjectMethodAttribute(DataObjectMethodType.Select, false)]
        public static PhotosetCollection GetPhotoSetsByUser(string userId, int photoSetPage, int setsPerPage)
        {
            Flickr flickr = new Flickr(ConfigurationManager.AppSettings["apiKey"],
                ConfigurationManager.AppSettings["secretKey"]);
            Flickr.CacheDisabled = true;
            return flickr.PhotosetsGetList(userId, photoSetPage, setsPerPage);
        }



Last thing to notice:
I had to add Flickr.CacheDisabled = true for the reason described here: http://flickrnet.codeplex.com/discussions/241542

So here is the full code of my FlickrBll.cs class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Web;
using FlickrNet;

namespace AntostalFestival.WebUI.Utilities
{
    [DataObject(true)]
    public class FlickrBLL
    {
        [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
        public static PhotosetPhotoCollection GetPagedSet(string setID, int maximumRows, int startRowIndex)
        {
            Flickr flickr = new Flickr(ConfigurationManager.AppSettings["apiKey"],
                ConfigurationManager.AppSettings["sharedSecret"]);
            PhotosetPhotoCollection photos = flickr.PhotosetsGetPhotos(setID, GetPageIndex(
                startRowIndex, maximumRows) + 1, maximumRows);
            Flickr.CacheDisabled = true;
            return photos;
        }

        public static int GetPagedSetCount(string setId)
        {
            Flickr flickr = new Flickr(ConfigurationManager.AppSettings["apiKey"],
                ConfigurationManager.AppSettings["sharedSecret"]);
            Flickr.CacheDisabled = true;
            Photoset set = flickr.PhotosetsGetInfo(setId);
            return set.NumberOfPhotos;
        }

        [DataObjectMethodAttribute(DataObjectMethodType.Select, false)]
        public static PhotosetCollection GetPhotoSetsByUser(string userId, int photoSetPage, int setsPerPage)
        {
            Flickr flickr = new Flickr(ConfigurationManager.AppSettings["apiKey"],
                ConfigurationManager.AppSettings["secretKey"]);
            Flickr.CacheDisabled = true;
            return flickr.PhotosetsGetList(userId, photoSetPage, setsPerPage);
        }

        private static int GetPageIndex(int startRowIndex, int maximumRows)
        {
            return (maximumRows <= 0) ? 0 : (int)Math.Floor((double)startRowIndex / (double)maximumRows);
        }

    }
}

Once you get all of this done this is what all of the above ends up as:


No comments:

Post a Comment