There are many examples of doing what you ask out there. This answer is broken into two parts. First you need to (on your UI page) figure out which images exist and show \ hide the images based on the results of the query. Next you need to use a page (or more appropriately an HttpHandler) to display the image on the page. I have mocked up a quick sample below. I have tried to comment the code to help you read through it.
Your ASPx page (Html)
<form id="form1" runat="server">
<div>
<asp:Image ID="Image1" runat="server" />
<asp:Image ID="Image2" runat="server" />
<asp:Image ID="Image3" runat="server" />
<asp:Image ID="Image4" runat="server" />
<asp:Image ID="Image5" runat="server" />
</div>
</form>
This is a simple page with 5 images. Your page will be quite a bit more complex but this is just for demo purposes. Next we will use the page-load event (or any other event) to look-up the images from the database and hide the images that are not uploaded.
The ASPx page (code)
protected void Page_Load(object sender, EventArgs e)
{
Session["memberreportid"] = 1; //TODO: Remove this
var query = "SELECT TOP 1 * FROM MemberReport where memberreportid=@p1";
//create the format string for each image. Note the last variable is {0} for additional formating
string imageSource = string.Format("/viewImage.ashx?memberreportid={0}&imageID={1}", Session["memberreportid"], "{0}");
//set our URL to our Image handler for each image
Image1.ImageUrl = string.Format(imageSource, 1);
Image2.ImageUrl = string.Format(imageSource, 2);
Image3.ImageUrl = string.Format(imageSource, 3);
Image4.ImageUrl = string.Format(imageSource, 4);
Image5.ImageUrl = string.Format(imageSource, 5);
//execute our command. Note we are using parameters in our SQL to circumvent SQL injection
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString))
{
var cmd = new SqlCommand(query, con);
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandTimeout = 3000;
cmd.Parameters.AddWithValue("@p1", Session["memberreportid"]);
con.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
//hide each image if the image is null or not a byte array (should always be a byte array)
if (reader["image1"] == null || !(reader["image1"] is byte[]))
Image1.Visible = false;
if (reader["image2"] == null || !(reader["image2"] is byte[]))
Image2.Visible = false;
if (reader["image3"] == null || !(reader["image3"] is byte[]))
Image3.Visible = false;
if (reader["image4"] == null || !(reader["image4"] is byte[]))
Image4.Visible = false;
if (reader["image5"] == null || !(reader["image5"] is byte[]))
Image5.Visible = false;
//we only want the first row so break (should never happen anyway)
break;
}
con.Close();
}
}
As you can see from the above we are simply doing a query to find which images are uploaded based on the ID found. If the image is null (or not a byte[]) then the image control is hidden.
The final piece is using a HttpHandler (GenericHandler from the New Item list). The HttpHandler is probably your best bet here as you don't need all the page generation events and can hook directly into the HttpHandler context. From here you can do pretty much everything you would like to do in an ASPx page (my personal implementation). Note by default the HttpHandler DOES NOT have access to the Session state.
Add a new GenericHandler called viewImage.ashx (or whichever you wish) and add the following code. Again this is commented to help read through.
viewImage.ashx code.
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Web;
namespace WebApplication1
{
/// <summary>
/// Summary description for viewImage
/// </summary>
public class viewImage : IHttpHandler
{
/// <summary>
/// process the request
/// </summary>
/// <param name="context">the current request handler</param>
public void ProcessRequest(HttpContext context)
{
///extract our params from the request
int memberID = 0, imageID = 0;
if (!int.TryParse(context.Request["memberreportid"], out memberID) ||
memberID <= 0 ||
!int.TryParse(context.Request["imageID"], out imageID) ||
imageID <= 0)
{
this.transmitError();
return;
}
//build our query
var query = string.Format("SELECT TOP 1 image{0} FROM MemberReport where memberreportid=@p1", imageID);
//execute the query
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString))
{
try
{
var cmd = new SqlCommand(query, con);
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandTimeout = 3000;
//set the member command type
cmd.Parameters.AddWithValue("@p1", memberID);
con.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
string psudoFileName = string.Format("memberReport_{0}_image{1}.png", memberID, imageID);
byte[] binary = reader[0] as byte[];
context.Response.ContentType = "image/png";
context.Response.AppendHeader("Content-Disposition", string.Format("filename=\"{0}\"", psudoFileName));
context.Response.AppendHeader("Content-Length", binary.Length.ToString());
context.Response.BinaryWrite(binary);
//todo: Implement your caching. we will use no caching
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
//we only want the first row so break (should never happen anyway)
break;
}
con.Close();
}
catch (Exception ex)
{
//TODO: Maybe some logging?
}
this.transmitError();
}
}
/// <summary>
/// transmits a non-image found
/// </summary>
void transmitError()
{
var context = HttpContext.Current;
if (context == null)
return;
//set the response type
context.Response.ContentType = "image/png";
//set as no-cache incase this image path works in the future.
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
//transmit the no-image found error
context.Response.TransmitFile(context.Server.MapPath("no-image.png"));
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Now this should be all you need to display the images on the page and be-able to show \ hide the images as they are uploaded.
Hope this helps.