Skip navigation

Build Your Own Photo Gallery: Part II

Managing Photos and Albums

CodeTalk

LANGUAGES: C#

ASP.NET VERSIONS: 2.0

 

Build Your Own Photo Gallery: Part II

Managing Photos and Albums

 

By Bipin Joshi

 

In Part I of this series we developed database tables, a data access class, and a PhotoHelper utility class. We also developed two master pages, AdminMasterPage.master and MasterPage.master. But before users can see any albums or photos, the administrator must upload them to the database. That s the topic of this installment of this three-part series on how to build your own photo gallery: we ll develop Web forms for managing albums and photos. The former will allow the administrator to create, edit, and delete album definitions; the latter will allow the administrator to upload photos and specify photo attributes, such as name, description, and thumbnail size.

 

Creating and Managing Albums

The first administrative step is to create and manage albums. We ll develop a Web form that allows creating and maintaining albums. Add a new Web form in the Admin folder called AlbumManager.aspx. Make sure to select the appropriate master page for it. Drag and drop a SQL Data Source control on it. Configure the SQL Data Source control to select AlbumID, Name, Description, and IsPublic columns from the Albums table (see Figure 1).

 


Figure 1: Configuring the SQL Data Source control.

 

Click the Advanced button and ensure that you generate the INSERT, UPDATE, and DELETE statements (see Figure 2).

 


Figure 2: Generating INSERT, UPDATE, and DELETE statements.

 

Now drag and drop a DetailsView control onto the Web form. Open the smart tags of DetailsView and set Data Source as SqlDataSource1. Also, enable paging, inserting, editing, and deleting, as shown in Figure 3.

 


Figure 3: Smart tags of DetailsView.

 

Note how ASP.NET automatically creates CheckBoxField for the byte column IsPublic. Listing One shows the complete markup of AlbumManager.aspx (unwanted markup has been removed). Figure 4 shows a sample run of the Web form.

 


Figure 4: Sample run of AlbumManager.aspx.

 

Managing Photos

Let s move on to managing photos. Add a new Web form in the Admin folder called PhotoManager.aspx selecting administrative master page. Before starting any coding let s see how the form is supposed to function.

 

The form displays a list of available albums in a DropDownList. Once an album is selected it displays all the photo thumbnails from that album, along with the name, description, and thumbnail size. You can add, edit, or delete the photos (see Figure 5). The photo entry panel appears when a user clicks the Add a new photo link, as shown in Figure 6.

 


Figure 5: List of photos from an album.

 


Figure 6: The photo entry panel.

 

The photo entry panel allows the administrator to upload photos and specify attributes such as name, description, and thumbnail size. Once the Save button is clicked, the photo is saved in the SQL Server database and assigned to the selected album.

 

Let s begin developing the form. Drag and drop a SQL Data Source control and configure it to select AlbumID and Name columns from the Albums table. Drag and drop a DropDownList on the Web form and from the smart tags of DropDownList select Choose Data Source. Configure the data source of the DropDownList to SqlDataSource1, as shown in Figure 7.

 


Figure 7: The Data Source Configuration Wizard for DropDownList.

 

Also, set the AutoPostBack property of the DropDownList to true. Now, drag and drop onto the Web form a LinkButton and a Panel control. Set the Text property of LinkButton to Add a new photo and add the code shown in Figure 8 in its click event handler.

 

protected void LinkButton3_Click(object sender, EventArgs e)

{

TextBox1.Text = "";

TextBox2.Text = "";

TextBox3.Text = "";

TextBox4.Text = "";

DataList1.SelectedIndex = -1;

ViewState["mode"] = "Add";

Panel1.Visible = true;

}

Figure 8: The click event handler of the Add a new photo link.

 

Note one important thing here. We set a ViewState variable called mode to Add . This variable will be used in the click event handler of the Save button to decide whether to update or insert a photo.

 

Design the panel as shown in Figure 6. Note that we use a FileUpload control for uploading the photos from the client machine to the database. Set the Visible property of the Panel to false. Listing Two shows the relevant markup.

 

Drag and drop a DataList control onto the Web form and design its ItemTemplate as shown in Figure 5. The complete markup of DataList is shown in Figure 9.

 

 BackColor="White" BorderColor="#999999" BorderStyle="None"

 BorderWidth="1px" CellPadding="3" GridLines="Vertical"

 OnItemDataBound="DataList1_ItemDataBound" OnItemCommand=

 "DataList1_ItemCommand" OnSelectedIndexChanged=

 "DataList1_SelectedIndexChanged">

'<%# Eval("Name") %>'>

 '<%# Eval("Description") %>'>

 '<%# Eval("thumbnailheight") %>'>

 

Text='<%# Eval("thumbnailwidth") %>'>

 CommandName="Edit">Edit

 CommandName="Delete">Delete

Figure 9: Markup of DataList.

 

Note how we used the Eval method to display required columns of the database table. Also, note that the CommandName property of the two LinkButtons is set to Edit and Delete, respectively. Next, add a method named BindDataList in the code-behind file PhotoManager.aspx.cs, as shown in Figure 10.

 

private void BindDataList(int albumid)

{

SqlParameter[] p = new SqlParameter[1];

p[0]= new SqlParameter("@albumid", albumid);

DataList1.DataSource= SqlHelper.ExecuteDataSet("select *

 from photos where albumid=@albumid",p);

DataList1.DataKeyField = "PhotoID";

DataList1.DataBind();

}

Figure 10: The BindDataList method.

 

The BindDataList method selects photos from the required album and binds the resultant DataSet to the DataList. It also sets the DataKeyField property of DataList to PhotoID. Now, add the SelectedIndexChanged event handler to the DropDownList, as shown in Figure 11.

 

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)

{

BindDataList(int.Parse(DropDownList1.SelectedValue));

}

Figure 11: SelectedIndexChanged event handler.

 

Here, we simply call the BindDataList function by passing the selected album ID. This way the DataList will display the photos from the selected album. Next, add the ItemDataBound event handler to the DataList, as shown in Figure 12.

 

protected void DataList1_ItemDataBound(object sender,

 DataListItemEventArgs e)

{

Image img = (Image)e.Item.FindControl("Image1");

if (img != null)

img.ImageUrl = "~/getphoto.aspx?imgtype=thumbnail&photoid=" + DataList1.DataKeys[e.Item.ItemIndex].ToString();

}

Figure 12: ItemDataBound event of DataList.

 

Here comes an interesting part. We want to display in the DataList a thumbnail of the actual photo. In the ItemDataBound event handler we get hold of the Image control using the FindControl method and set its ImageUrl property to GetPhoto.aspx along with two query string parameters: imgtype and photoid. The imgtype parameter indicates whether we want to retrieve a thumbnail or full image, and the photoid parameter indicates the ID of the photo. Later we ll develop GetPhoto.aspx, which emits the thumbnail of a photo on the fly on the response stream.

 

To Edit or Delete images we handle the ItemCommand event of DataList. Figure 13 shows the code of this event handler.

 

protected void DataList1_ItemCommand(object source,

 DataListCommandEventArgs e)

{

if (e.CommandName == "Edit")

{

int photoid=(int)DataList1.DataKeys[e.Item.ItemIndex];

TextBox1.Text = ((Label)e.Item.FindControl("Label2")).Text;

TextBox2.Text = ((Label)e.Item.FindControl("Label3")).Text;

TextBox3.Text = ((Label)e.Item.FindControl("Label10")).Text;

TextBox4.Text = ((Label)e.Item.FindControl("Label12")).Text;

ViewState["mode"] = "Edit";

DataList1.SelectedIndex = e.Item.ItemIndex;

Panel1.Visible = true;

}

if (e.CommandName == "Delete")

{

string sql = "delete from photos where photoid=@photoid";

SqlParameter[] p = new SqlParameter[1];

p[0] = new SqlParameter("@photoid",

 DataList1.DataKeys[e.Item.ItemIndex]);

SqlHelper.ExecuteNonQuery(sql, p);

BindDataList(int.Parse(DropDownList1.SelectedValue));

}

}

Figure 13: The ItemCommand event handler.

 

We check CommandName to decide which button has been clicked (Edit or Delete). If Edit has been clicked we populate the photo entry panel with the details from the current record and set its Visible property to true. Note one important thing here. We set the mode ViewState variable to Edit. This variable is later used in the click event handler of the Save button to decide whether to update or insert a record. On the other hand, if the Delete button has been clicked, we delete that record from the database and rebind the DataList to reflect the changes. Finally, handle the click event of the Save button, as shown in Figure 14.

 

protected void Button1_Click(object sender, EventArgs e)

{

if (ViewState["mode"].ToString() == "Add")

{

Stream imgdatastream = File1.PostedFile.InputStream;

int imgdatalen = File1.PostedFile.ContentLength;

byte[] imgdata = new byte[imgdatalen];

int n = imgdatastream.Read(imgdata, 0, imgdatalen);

string sql = "INSERT INTO PHOTOS(ALBUMID,NAME,DESCRIPTION,

 IMAGE,THUMBNAILHEIGHT,THUMBNAILWIDTH)

 VALUES(@albumid,@name,@desc,@image,@ht,@wt)";

SqlParameter[] p = new SqlParameter[6];

p[0] = new SqlParameter("@albumid",

 DropDownList1.SelectedValue);

p[1] = new SqlParameter("@name", TextBox1.Text);

p[2] = new SqlParameter("@desc", TextBox2.Text);

p[3] = new SqlParameter("@image", imgdata);

p[4] = new SqlParameter("@ht", TextBox3.Text);

p[5] = new SqlParameter("@wt", TextBox4.Text);

SqlHelper.ExecuteNonQuery(sql, p);

BindDataList(int.Parse(DropDownList1.SelectedValue));

}

if (ViewState["mode"].ToString() == "Edit")

{

Stream imgdatastream = File1.PostedFile.InputStream;

int imgdatalen = File1.PostedFile.ContentLength;

byte[] imgdata = new byte[imgdatalen];

int n = imgdatastream.Read(imgdata, 0, imgdatalen);

string sql = "UPDATE PHOTOS SET NAME=@name,DESCRIPTION=@desc,IMAGE=@image,

 THUMBNAILHEIGHT=@ht,THUMBNAILWIDTH=@wt

 WHERE PHOTOID=@id";

SqlParameter[] p = new SqlParameter[6];

p[0] = new SqlParameter("@name", TextBox1.Text);

p[1] = new SqlParameter("@desc", TextBox2.Text);

p[2] = new SqlParameter("@image", imgdata);

p[3] = new SqlParameter("@ht", TextBox3.Text);

p[4] = new SqlParameter("@wt", TextBox4.Text);

p[5] = new SqlParameter(

 "@id",DataList1.DataKeys[DataList1.SelectedIndex]);

SqlHelper.ExecuteNonQuery(sql, p);

     BindDataList(int.Parse(DropDownList1.SelectedValue));

}

Panel1.Visible = false;

}

Figure 14: The click event handler of Save button.

 

If the ViewState variable mode is set to Add we INSERT the new image in the database. The code marked in bold is a very important piece of code. Here, we access the incoming stream of uploaded file using the File1.PostedFile.InputStream property. We then find out the length of this stream using the ContentLength property. Then we read the uploaded image in a byte array. This byte array is used further while inserting the record in the database. We then form an INSERT query and create the required parameters. To add the image in the database we call the ExecuteNonQuery method of the SqlHelper class.

 

Along the same lines, if the mode is set to Edit we form an UPDATE query with required parameters and fire it using the ExecuteNonQuery method.

 

Conclusion

Before end users can see any photos it is essential to upload them in the database. Photos are categorized into albums. We created Web forms for creating, editing, and deleting album definitions. Album definitions include name, description, date of creation, and a flag indicating whether the album is public or private. Public albums can be viewed by anybody without registering with the Web site. On the other hand, private albums can be accessed only by registered users. We used data bound controls such as DataList that display thumbnail images of photos. This ability is not available out of the box, but with some tweaking we made it possible. The actual logic of how it works will be demystified in Part III, wherein we ll also develop album and photo pages.

 

The sample code for this series is available for download.

 

Bipin Joshi is the founder and owner of BinaryIntellect Consulting (http://www.binaryintellect.com), where he conducts professional training programs on .NET technologies. He is the author of Developer s Guide to ASP.NET 2.0 (http://www.binaryintellect.com/books) and co-author of three WROX books on .NET 1.x. He writes regularly for http://www.DotNetBips.com, a community Web site he founded in the early days of .NET. He is a Microsoft MVP, MCAD, MCT, and member of ASPInsiders. He jots down his thoughts about .NET, life, and Yoga at http://www.bipinjoshi.com. He also conducts workshops on Yoga and Meditation, where he helps IT professionals develop a positive personality. You can contact him at mailto:[email protected].

 

Begin Listing One Markup of AlbumManager.aspx

<%@ Page Language="C#" MasterPageFile="~/Admin/

 AdminMasterPage.master" AutoEventWireup="true"

 CodeFile="AlbumManager.aspx.cs" Inherits=

 "Admin_ AlbumManager" Title="Untitled Page" %>

 "ContentPlaceHolder1" Runat="Server">

 AllowPaging="True" AutoGenerateRows="False"

 DataKeyNames="AlbumID" DataSourceID="SqlDataSource1"

Height="50px" Width="100%" BackColor="White"

 BorderColor="#999999" BorderStyle="None" BorderWidth="1px"

 CellPadding="3" GridLines="Vertical">

 InsertVisible="False" ReadOnly="True"

SortExpression="AlbumID" />

 SortExpression="Name" />

 SortExpression="Description">

 Text='<%# Bind("Description") %>'

 TextMode="MultiLine">

 Text='<%# Bind("Description") %>'

 TextMode="MultiLine">

 Text='<%# Bind("Description") %>'>

 HeaderText="Is Public :" SortExpression="IsPublic" />

 ShowEditButton="True" ShowInsertButton="True"

 InsertText="Save" NewText="Add" />

 ConnectionString="<%$ ConnectionStrings:ConnectionString %>"

DeleteCommand="DELETE FROM [Albums] WHERE [AlbumID] =

 @AlbumID" InsertCommand="INSERT INTO [Albums] ([Name],

  [Description], [IsPublic]) VALUES (@Name, @Description,

 @IsPublic)"

SelectCommand="SELECT [AlbumID], [Name], [Description],

  [IsPublic] FROM [Albums] ORDER BY [Name]"

UpdateCommand="UPDATE [Albums] SET [Name] = @Name,

  [Description] = @Description, [IsPublic] =

 @IsPublic WHERE [AlbumID] = @AlbumID">


 EnableViewState="False" Font-Bold="True"

 ForeColor="Red">

End Listing One

 

Begin Listing Two Markup of photo entry panel

 Visible="False" Width="100%">

 Text="Photo :">

 Text="Name :">

 runat="server">

 Text="Description :">

 TextMode="MultiLine">

 Text="Thumbnail Height :">

 runat="server">

Text="Thumbnail Width :">

 runat="server">

 OnClick="Button1_Click" Text="Save" />

End Listing Two

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish