Click here to Skip to main content
Click here to Skip to main content

Microsoft Personal Web Site Starter Kit – Random Image Web User Control

, 29 Mar 2006
Rate this:
Please Sign up or sign in to vote.
How to create a web user control to show a random photo on the home page of Microsoft Personal Web Site Starter Kit
Random Photo Web User Control

Introduction

Microsoft's Starter Kits provide a great hands on experience for developers and make the learning process of the .Net technology real fun. One of them is Microsoft Personal Web Site Starter Kit. It provides a complete, ready to run, ready to customize, interactive Web site for sharing photos, posting your résumé, categorized links and more.

Below are listed some links related to Personal Web Site Starter Kit:

This article will show you how to customize the existing code by creating a web user control to show a random photo on the home page. It does not add new functionality but rather provides a different solution for selecting a random photo that I personally think is more effective.

For simplicity I am going to use the abbreviation PWS to refer to Personal Web Site Starter Kit.

Using the code

The ZIP file contains only the files that have been modified. In order to try the code you first need to download, install and configure the original PWS package from Microsoft's web site. Then you can just overwrite the existing files with the files from the ZIP file provided here. I highly recommend creating a backup copy of the original files before applying the changed code.

If you prefer to do it the hard way keep reading the following paragraphs. I will guide you step by step on creating the web control providing you have PWS installed properly and you have the solution opened in your Visual Studio 2005.

Right-click the project and choose New Folder from the context menu. Change the default folder name to UserControls. Right-click the newly created folder and choose Add New Item. Navigate to Web User Control, name it RandomPhoto.ascx and press Add button. This will add two files to your project that will contain the user interface and the code for the user control:

The User Control

The next step is to adjust Default.aspx page to use our new control instead of existing code. Open Default.aspx page and add the following just below the <@ Page directive:

<%@ Register Src="UserControls/RandomPhoto.ascx" TagName="RandomPhoto" TagPrefix="uc1" %>

Replace the following code:

<asp:formview id="FormView1" runat="server" datasourceid="ObjectDataSource1" ondatabound="Randomize" cellpadding="0" borderwidth="0" enableviewstate="false">
 <ItemTemplate>
 ....
 </ItemTemplate>
</asp:formview>

with this one:

<uc1:RandomPhoto ID="RandomPhoto1" DataSourceID="ObjectDataSource1" runat="server" />

It is time to put some content to our user control. The RandomPhoto.ascx page will contain a code very similar to those we just deleted from our Default.aspx page. Below you can find it:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="RandomPhoto.ascx.cs" Inherits="Admin_UserControls_RandomPhoto" %>
<asp:formview runat="server" ID="FormView" cellpadding="0" borderwidth="0" enableviewstate="false">
    <ItemTemplate>
        <h4><%# Title %></h4>
        <table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
            <tr>
                <td class="topx--"></td>
                <td class="top-x-"></td>
                <td class="top--x"></td>
            </tr>
            <tr>
                <td class="midx--"></td>
                <td><a href="Details.aspx?AlbumID=<%# Eval("AlbumID") %>&Page=<%# Eval("Page") %>">
                    <img src="Handler.ashx?PhotoID=<%# Eval("PhotoID") %>&Size=M" class="photo_198" style="border:4px solid white" 
                    alt='Photo Number <%# Eval("PhotoID") %>' /></a></td>
                <td class="mid--x"></td>
            </tr>
            <tr>
                <td class="botx--"></td>
                <td class="bot-x-"></td>
                <td class="bot--x"></td>
            </tr>
        </table>
        <p><%# Text %></p>
        <p><a href="Download.aspx?AlbumID=<%# Eval("AlbumID") %>&Page=<%# Eval("Page") %>">
            <asp:image runat="Server" id="DownloadButton" AlternateText="download photo" skinid="download"/></a></p>
        <p>See <a href="<%# "Albums.aspx" %>">more photos </a></p>
        <hr />
    </ItemTemplate>
</asp:formview>

Our control will expose three properties that will make it easier for customizations:

  • DataSourceID - stores the ID of ObjectDataSource object through which data is retrieved from database 
  • Title - a line of text above the photo
  • Text - the text to be displayed below the photo

The code <%# Title %> will be replaced with the value of the Title property.

Another interesting point here is the following code:

<a href="<%# "Albums.aspx" %>">more photos </a>

We cannot use the simpler <a href="Albums.aspx">more photos </a> because Visual Studio will complain it cannot find Albums.aspx in the folder where user control resides. Instead we have to use the code shown above which is executed at run time and does not cause any troubles at design time.

Now lets have a look at the code behind page for our user control. The content of the RandomPhoto.ascx.cs is shown below:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;

public partial class Admin_UserControls_RandomPhoto : System.Web.UI.UserControl
{
    #region Properties

    [CategoryAttribute("Data")]
    [Description("The ID of the ObjectDataSource")]
    public string DataSourceID
    {
        get
        {
            return _DataSourceID;
        }

        set
        {
            _DataSourceID = value;
            this.FormView.DataSourceID = _DataSourceID;
        }
    } private string _DataSourceID = string.Empty;

    [CategoryAttribute("Data")]
    [Description("The text above the photo")]
    [DefaultValue("Photo of the Day")]
    public string Title
    {
        get
        {
            return _Title;
        }

        set
        {
            _Title = value;
        }
    } private string _Title = "Photo of the Day";

    [CategoryAttribute("Data")]
    [Description("The text below the photo")]
    [DefaultValue("This is the photo of the day")]
    public string Text
    {
        get
        {
            return _Text;
        }

        set
        {
            _Text = value;
        }
    } private string _Text = "This is the photo of the day";

    #endregion

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

There is nothing special about the code. We define the three properties I mentioned about earlier. These properties can be set up manually in the code like this:

<uc1:RandomPhoto ID="RandomPhoto1" DataSourceID="ObjectDataSource1" Title="Random photo" Text="lorem ipsum" runat="server" />

The other way is to use the Properties Window:

Properties Window

Most probably you already are wondering how we are going to get the image and how we can make sure it is randomly selected. We are going to add a new method to PhotoManager.cs. Here is the code:

public static PhotoExt GetRandomPhoto()
{
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Personal"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand("GetRandomPhoto", connection))
        {
            command.CommandType = CommandType.StoredProcedure;
            bool filter = !(HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators"));
            command.Parameters.Add(new SqlParameter("@IsPublic", filter));
            connection.Open();
            List<PhotoExt> list = new List<PhotoExt>();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                reader.Read();
                PhotoExt photo = new PhotoExt((int)reader["PhotoID"], (int)reader["AlbumID"], (string)reader["Caption"], (int)reader["Page"]);
                return photo;
            }
        }
    }
}

This method will return an object of type PhotoExt. PhotoExt inherits Photo class by adding a property Page. Add the following code at the end of Photo.cs file.

public class PhotoExt : Photo
{

    private int _page;

    public int Page { get { return _page; } }

    public PhotoExt(int id, int albumid, string caption, int page)
        : base(id, albumid, caption)
    {
        _page = page;
    }
}

GetRandomPhoto() method uses a stored procedure GetRandomPhoto to get the data from the database. This is the place where randomization takes place. The SQL script is provided with create_GetRanomPhoto.sql file that is part of the ZIP file attached to this article. The SQL script is shown below:

CREATE PROCEDURE [dbo].[GetRandomPhoto]
  @IsPublic bit
AS
  SELECT TOP 1
    [Albums1].AlbumID
    , [Photos1].PhotoID
    , [Photos1].Caption
    , Page = COUNT(*) - 1
  FROM [Albums] Albums1, [Photos] Photos1, [Albums] Albums2, [Photos] Photos2
  WHERE
        [Albums1].AlbumID = [Photos1].AlbumID
    AND [Albums2].AlbumID = [Photos2].AlbumID
    AND [Photos1].PhotoID >= [Photos2].PhotoID
    AND [Albums1].AlbumID = [Albums2].AlbumID
    AND ([Albums1].IsPublic = @IsPublic OR [Albums1].IsPublic = 1)
  GROUP BY [Albums1].AlbumID, [Photos1].PhotoID, [Photos1].Caption
  ORDER BY NEWID()

RETURN

You have to run this script against the Personal.mdf database to create the stored procedure.

It returns exactly one record with information about the photo, album and page number which is calculated field. The use of NEWID() guarantees the record is randomly selected.

We still have some work to be done with the Default.aspx page and its code behind. Change the ObjectDatasource to use the new method we added to PhotoManager:

<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PhotoManager" SelectMethod="GetRandomPhoto" />

The last thing is to comment or completely remove Randomize method from Default.aspx.cs file:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Default_aspx  : System.Web.UI.Page {

  /*
  public void Randomize(object sender, EventArgs e) {
    Random r = new Random();
    FormView1.PageIndex = r.Next(FormView1.PageCount);
  }
  */
}

Congratulations! You are done. Compile the project, cross your fingers and see if it works.

Conclusion

I hope this article will give some ideas to people using Microsoft Personal Web Site Starter Kit on how to customize their web sites using custom controls.

I would love to hear your opinion and suggestions.

History

  • 8 March 2006 - Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

anichin
Web Developer
Canada Canada
Angel Anichin is experienced .Net developer living in Canada.
 
Expertise: ASP.NET, C#, MS Content Management Server, MS SQL Server, Oracle, HTML, JavaScript, CSS
 
Hobbies: Digital Photography, Skiing
Follow on   LinkedIn

Comments and Discussions

 
GeneralGood job! I linked your page to mine PinmemberSue_NC15-Apr-06 4:13 
GeneralRe: Good job! I linked your page to mine Pinmemberanichin15-Apr-06 12:42 
GeneralRe: Good job! I linked your page to mine Pinmemberjoyjjjz22-Oct-07 21:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 29 Mar 2006
Article Copyright 2006 by anichin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid