Introduction
In this article, I will talk about profiles with images. The best way to personalize your web application is through profiles, and ASP.NET provides lot of out of the box features to implement them. We all agree that an application with images looks better than an application with just plain text, and we need to store the images of users to make our web application more appealing and user friendly.
This is what I am trying to achieve.
- The Home page showing the image of the user, after the user logs in.
- After clicking on the image, change your avatar (image). A popup shows up and the user can select one from any of the available images.
- After clicking on an image of your choice, the image changes. Here, I click on "user.png":
Isn't that easy? I achieve all this through Profiles. And, the best part is that I do all this with less than 20 lines of code.
Background
In this article, I will directly go into Profiles without talking about Forms Authentication, Membership, Authorization etc. I hope you find some good books and good online resources for those because there are many available.
Using the Code
Implementing Profiles is very straightforward; you just have to add a few lines in your web.config.
Here is my Profile Provider in the Web.Config of my application:
<profile defaultProvider="TestPofileProvider" automaticSaveEnabled="false" enabled="true">
<providers>
<clear/>
<add name="TestProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="MembershipConnectionString"
applicationName="EffortTracker"/>
</providers>
<properties>
<add name="FirstName" type="String"/>
<add name ="LastName" type="String"/>
<add name="DateOfBirth" type="DateTime"/>
<add name="Avatar" type="String"/>
<add name="ProjectName" type="String" />
</properties>
</profile>
connectionStringName
is the name of the connection string that connects to the "aspnetdb" fatabase, which has all the tables related to roles, users and profiles etc.
Properties
is the list of all the properties you want to remember for a user. I would like my application to remember the user's first name, last name, date of birth, avatar (which is the image of the user) and the project name. type
denotes the data type. You must be wondering why I set the data type of the image property as String
. It has to be something like System.Drawing.Bitmap
, isn't it? I will clarify that in the coming section. You can add any property and any number of properties you want.
Creating and Updating Profiles
In this section, I will tell you how to create Profiles in the code-behind. Creating Profiles is very straightforward, and takes only a few lines of code.
ProfileBase p1 = ProfileBase.Create("test"); p1.SetPropertyValue("FirstName", "test");
p1.SetPropertyValue("LastName", "user");
p1.SetPropertyValue("DateOfBirth", Convert.ToDateTime("12/08/1985"));
p1.SetPropertyValue("Avatar", "Images/user.jpg");
p1.SetPropertyValue("ProjectName", "Test-Project");
p1.Save();
If you are using a website instead of a web application, then you will get a strongly typed object called Profile
(which denotes the Profile of the user logged in). You can set the values directly, like:
Profile.FirstName = "test";
Profile.LastName = "user";
I am using a web application, and that's why I had to set the property like p1.SetPropertyValue("FirstName", "test");
, which is a little messy, but it works.
Now I think it must be clear how the Avatar
data type is a String
, instead of a Bitmap
. Actually, I store the path of the images in the database, instead of directly storing the image as binary. By using this technique, you can save yourself a lot of coding and a lot of time. I created a folder called "Images" in my web application directory, which will store all my images.
I have created an ASPX page called Home, which will be the landing page for my application. In this page, there will be an ImageButton
which will show the image of the user who is logged in and also will allow the user to change the image (avatar), and that's why I have chosen an ImageButton
.
This is the ASPX markup:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
</td>
<td>
<asp:ImageButton ID="ProfileImage" runat="server"
BorderWidth="1px" Height="100px"
Width="100px" BorderStyle="Outset" />
</td>
</tr>
</table>
<asp:Panel ID="modalPanel" runat="server"
Visible="true" BackColor="CadetBlue" Width="250px"
BorderWidth="1px" BorderStyle="Outset" ScrollBars="Auto">
<table>
<tr>
<td style="background-color:Gray;">Change Avatar </td>
</tr>
<tr> <td>
<asp:DataList ID="AvatarView" runat="server"
RepeatDirection="Vertical" RepeatLayout="Flow"
RepeatColumns="3" CellSpacing="2"
ItemStyle-BorderWidth="1px" ItemStyle-BorderStyle="Groove">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl='<%# Eval("Name","~\\Images\\{0}") %>'
Height="50px" Width="50px"
onclick="ImageButton1_Click1" ToolTip='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:DataList></td>
</tr>
</table>
</asp:Panel>
<cc1:ModalPopupExtender ID="ModalPopupExtender1"
runat="server" TargetControlID="ProfileImage"
PopupControlID="modalPanel"></cc1:ModalPopupExtender></div>
</form>
</body>
</html>
As you can see from the ASPX page, I have an ImageButton
named ProfileImage
which will show the image and allow the user to change the image. I also have a ModalPopupExtender
AJAX control which will open up a popup with all the images that are available in my Images folder (which I was referring to earlier). I have used a DataList
to show all the images in that folder, and each item in the DataList
is an ImageButton
which causes a postback so that the path of the new avatar is updated in the Profile database.
The DataList
shows all the images that are there in the Images folder. Here is how I populate my DataList
. I get all the files from the directory "Images" using the DirectoryInfo
class of System.IO
.
DirectoryInfo dir = new DirectoryInfo(Server.MapPath("Images"));
AvatarView.DataSource = dir.GetFiles();
AvatarView.DataBind();
Here is the ASPX mark up of my DataList
named AvatarView
:
<asp:DataList ID="AvatarView" runat="server"
RepeatDirection="Vertical" RepeatLayout="Flow"
RepeatColumns="3" CellSpacing="2"
ItemStyle-BorderWidth="1px" ItemStyle-BorderStyle="Groove">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl='<%# Eval("Name","~\\Images\\{0}") %>'
Height="50px" Width="50px"
onclick="ImageButton1_Click1" ToolTip='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:DataList>
In the ItemTemplate
, I use an ImageButton
to show each image. I map the ImageUrl
of the ImageButton
to the Name
property of the FileInfo
object which dir.GetFiles()
returns.
Here is the code to update your Profile:
protected void ImageButton1_Click1(object sender, ImageClickEventArgs e
{
ImageButton newAvatar = (ImageButton)sender;
HttpContext.Current.Profile.SetPropertyValue("Avatar", newAvatar.ImageUrl);
HttpContext.Current.Profile.Save();
ProfileImage.ImageUrl = HttpContext.Current.Profile["Avatar"].ToString();
Server.Transfer("Home.aspx");
}
Each button is wired to a Click
event; if you click on any ImageButton
in the DataList
, the above event fires and it changes the Avatar
property of your Profile and reloads the page so that you can see the changes.
Now, if you were to implement all this without using Forms Authentication, it would have taken a hell of a lot of time, but thanks to Forms Authentication, I was able to do this in two hours. And also, this is just the tip of the iceberg; there is so much you can do, and it all depends on your imagination, and I would say: "sky is the limit".