Database Setup
Let’s start first with the database setup. I’m using SQL Server 2008, but SQL Server 2008 Express, SQL Server 2005, and SQL Server 2005 Express should work equally as well.Using SQL Server Management Studio I created a new database called TestDB. I then added the ASP.NET Membership, Roles, and Profile providers to the database with the following command:
aspnet_regsql –S . –E –A mrp –d TestDB
You can enter aspnet_regsql /? for a list of available options.
Once I had all of the appropriate tables, stored procedures, views, etc. added to my database I created a table called aspnet_UserImages. This table contains the following columns:
- UserId
- ImageId
- Image
I’ve included two stored procedures along with the sample that insert and retrieve the uploaded image associated with the user’s account. I’ve also included a script that will create the aspnet_UserImages table along with the foreign key constraint mentioned earlier.
New User Registration
I’ve converted the CreateUserWizard to a template and added a FileUpload control to it, so that users can upload an image of their choice at the time they create their account.
The code is pretty straightforward a few things to note though. First I save the user’s entered username into a session variable and later retrieve it when the user logs in, so that it can be used in retrieving the image that is associated with the user’s account. Another thing I’ve done is incorporated code to resize the uploaded image, so that you can control to a degree the amount of space the images will consume within your database. Finally I check the file extension, so that only the types defined are accepted, if a non-supported file type is uploaded the user account is not created.
protected void NewUserWizard_CreatingUser(object sender, LoginCancelEventArgs e)
{
Label invalidFile = (Label)CreateUserWizardStep1.ContentTemplateContainer.FindControl("ErrorLabel");
FileUpload userImage = (FileUpload)CreateUserWizardStep1.ContentTemplateContainer.FindControl("UserImageFileUpload");
// Check whether we have a file to save or not.
if (userImage.HasFile)
{
// Check that the file type is supported.
string fileExtension = Path.GetExtension(userImage.PostedFile.FileName);
switch (fileExtension)
{
case ".gif":
break;
case ".jpg":
case ".jpeg":
break;
case ".png":
break;
default:
invalidFile.Visible = true;
invalidFile.Text = "Supported file types are GIF, JPG, PNG.";
e.Cancel = true;
break;
}
}
}
User login
I have a default.aspx page that the user is redirected to upon successful authentication. This page contains the code that gets the user’s Guid and then passes it to a Generic Handler via querystring, which in turn gets the image associated with the user’s account and displays it.
private void DisplayUserImage()
{
if (Session["UserName"] != null)
{
MembershipUser user = Membership.GetUser(Session["UserName"].ToString());
Guid userGuid = (Guid)user.ProviderUserKey;
UserImage.ImageUrl = "Image.ashx?userGuid=" + userGuid;
}
}
The handler that retrieves the user’s image associated with their account.
public void ProcessRequest (HttpContext context)
{
string userGuid = string.Empty;
// Check that the querystring value is not null.
if (context.Request.QueryString["userGuid"] != null)
{
userGuid = context.Request.QueryString["userGuid"];
}
else
{
throw new ArgumentException("Missing user id.");
}
context.Response.ContentType = "image/jpeg";
// Pass the user's guid in, so that we can get the image associated with the logged in user.
Stream strm = GetImage(userGuid);
byte[] buffer = new byte[2048];
int byteSeq = strm.Read(buffer, 0, 2048);
while (byteSeq > 0)
{
context.Response.OutputStream.Write(buffer, 0, byteSeq);
byteSeq = strm.Read(buffer, 0, 2048);
}
}
public Stream GetImage(string id)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString))
{
try
{
using (SqlCommand cmd = new SqlCommand("GetUserImage", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@UserId", id);
conn.Open();
byte[] img = (byte[])cmd.ExecuteScalar();
try
{
return new MemoryStream(img);
}
catch
{
return null;
}
finally
{
conn.Close();
}
}
}
catch (SqlException sqlEx)
{
throw sqlEx;
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
MembershipWithImage