Tuesday, October 25, 2011

Displaying User Associated Membership Image

I recently came across a post in the ASP.NET forums where a user had a need to allow users of his web site to upload an image during account creation. The user’s image was then redisplayed upon successful login into the website. I decided to put a little sample together detailing how this could be accomplished.

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 created a foreign key linking the UserId column from the aspnet_Users table to the UserId of the aspnet_UserImages table. In addition the Delete Rule within the aspnet_UserImages table was set to Cascade. Doing this allows the user’s image associated with the UserId to be deleted from the aspnet_UserImages table when the user’s account is removed via the Web Site Administration Tool or via SQL Server Management Studio directly.
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.
image
image
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.

image

image

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

Thursday, June 9, 2011

Useful .Net Tools

I thought I’d share a small list of free and open source .Net tools that you might find useful during your development efforts. I’ll continue to add to this list as I learn of new tools.
Profiling Tools
Slimetune - http://code.google.com/p/slimtune/
xteprofiler - http://www.xteprofiler.com/
Prof-It for C# - http://dotnet.jku.at/projects/Prof-It/Default.aspx

Decompilers
JustDecompile - http://www.telerik.com/products/decompiling.aspx
dotPeek EAP - http://www.jetbrains.com/decompiler/
ILSpy - http://wiki.sharpdevelop.net/ilspy.ashx

Load Testing Tools
loadUI - http://www.eviware.com/loadUI/whats-new-in-loadui-15.html
openSTA - http://opensta.org/
storm - http://storm.codeplex.com/

Functional Testing Tools
soapUI - http://www.eviware.com/soapUI/what-is-soapui.html
WebAii Testing Framework - http://www.telerik.com/automated-testing-tools/webaii-framework-features.aspx