MVC ASP.NET Identity Customizing For Adding Profile Image

profileIntroduction
  1. In our previous article, we have explained about how to customize ASP.NET MVC 5 Security and create user role and its base Menu Management (Dynamic menu using MVC and AngularJS)

In this article, we will see in detail about using ASP.NET identity in MVC Application,

  1. To upload and store User Profile Image to AspNetUsers table in SQL Server.

  2. Display the authenticated Logged in users, Uploaded profile Image in home page and in Title bar.

Prerequisites

  • Visual Studio 2015 - You can download it from here

Using the code

Step 1: Create Database.

First, we create a database to store all our ASP.NET identity details to be stored in our Local SQL Server. Here, we have used SQL Server 2014.Run the script as shown below in your SQL Server to create a database. 

  1. USE MASTER  
  2. GO  
  3.   
  4.  --1) Check for the Database Exists .If the database is exist then drop and create new DB  
  5.   
  6. IF EXISTS (SELECT [nameFROM sys.databases WHERE [name] = 'UserProfileDB' )  
  7. DROP DATABASE UserProfileDB  
  8.   
  9. GO  
  10.   
  11. CREATE DATABASE UserProfileDB  
  12. GO  
  13.   
  14. USE UserProfileDB  
  15. GO  
Step 2: Create your Web Application in Visual Studio 2015.

After installing our Visual Studio 2015, click Start -> Programs-> Visual Studio 2015-> Visual Studio 2015.
 
New-> Project-> Web -> ASP.NET Web Application. Enter your project name and click OK.
 
Select MVC and click OK. 



Step 3: Web.Config

In web.config file, we can find the DefaultConnection string. By default ASP.NET, MVC will use this connection string to create all ASP.NET identity related tables like AspNetUsers, etc. Here, in connection string, we will be using our newly created DB name.

Here, in connection string, change your SQL Server Name, UID and PWD to create and store all user details in one database. 

  1. <connectionStrings>    
  2.     <add name="DefaultConnection" connectionString="data source=YOURSERVERNAME;initial catalog=UserProfileDB;user id=UID;password=PWD;Integrated Security=True" providerName="System.Data.SqlClient"  />     
  3.  </connectionStrings>  
Step 4: IdentityModels.cs

In IdentityModels.cs, we need to add the image property to be used for storing our image to the database. In ApplicationUser class, we will be adding a new property to store the image and declare the property type as byte as shown below: 

  1. public class ApplicationUser : IdentityUser  
  2. {  
  3.     // Here we add a byte to Save the user Profile Pictuer  
  4.     public byte[] UserPhoto { getset; }  
  5.    //We can find this class inside the In IdentityModels.cs in Model folder  
 
  
Step 5: MVC Model Part.

In AccountViewModel.cs, check for the RegisterViewModel and add the properties as shown below:

  1. [Display(Name = "UserPhoto")]  
  2. public byte[] UserPhoto { getset; }  
 
 

Step 6: Edit Register view to add our upload image.

In Register.cshtml, we add the code shown  below to upload images to AspNetUsers table in our DB.

First we add , enctype = "multipart/form-data" in begin form, as shown below:
  1. @using(Html.BeginForm("Register""Account", FormMethod.Post, new {  
  2.     @class = "form-horizontal", role = "form", enctype = "multipart/form-data"  
  3. })) {  
Next, we need to customize our Register page to add the HTML Image Tag to upload the image. 
  1. <div class="form-group">  
  2.     @Html.LabelFor(m => m.UserPhoto, new { @class = "col-md-2 control-label" })  
  3.    <div class="col-md-10">  
  4.              
  5.       <input type="file" name="UserPhoto" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" />  
  6.              
  7.    </div>  
  8. </div>  
 
 
Step 7: MVC Controller Part,

  

In AccountController.cs, we will update the code in Register post method to customize and store the uploaded user image in ASP.NET identity database.

In the Register post method, we will save the uploaded image to the byte array and use this byte array result is to be saved in our users table. 
  1. if (ModelState.IsValid) {  
  2.   
  3.     // To convert the user uploaded Photo as Byte Array before save to DB    
  4.     byte[] imageData = null;  
  5.     if (Request.Files.Count > 0) {  
  6.         HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];  
  7.   
  8.         using(var binary = new BinaryReader(poImgFile.InputStream)) {  
  9.             imageData = binary.ReadBytes(poImgFile.ContentLength);  
  10.         }  
  11.     }  
  12.     var user = new ApplicationUser {  
  13.         UserName = model.Email, Email = model.Email  
  14.     };  
  15.   
  16.     //Here we pass the byte array to user context to store in db    
  17.     user.UserPhoto = imageData;  
Here is the complete code of the Register post method.
  1. [HttpPost]    
  2. [AllowAnonymous]    
  3. [ValidateAntiForgeryToken]    
  4. public async Task<ActionResult> Register([Bind(Exclude = "UserPhoto")]RegisterViewModel model)    
  5. {    
  6.     if (ModelState.IsValid)    
  7.     {    
  8.              
  9.         // To convert the user uploaded Photo as Byte Array before save to DB    
  10.         byte[] imageData = null;    
  11.         if (Request.Files.Count > 0)    
  12.         {    
  13.             HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];    
  14.   
  15.             using (var binary = new BinaryReader(poImgFile.InputStream))    
  16.             {    
  17.                 imageData = binary.ReadBytes(poImgFile.ContentLength);    
  18.             }    
  19.         }    
  20.   
  21.   
  22.         var user = new ApplicationUser { UserName = model.Email, Email = model.Email };    
  23.   
  24.         //Here we pass the byte array to user context to store in db    
  25.         user.UserPhoto = imageData;    
  26.   
  27.         var result = await UserManager.CreateAsync(user, model.Password);    
  28.         if (result.Succeeded)    
  29.         {    
  30.             await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);    
  31.                 
  32.             // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771    
  33.             // Send an email with this link    
  34.             // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);    
  35.             // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);    
  36.             // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");    
  37.   
  38.             return RedirectToAction("Index""Home");    
  39.         }    
  40.         AddErrors(result);    
  41.     }    
  42.   
  43.     // If we got this far, something failed, redisplay form    
  44.     return View(model);    
  45. }  
Now, we have successfully completed the Image uploading part to AspNetUsers Table in our local SQL Server Database.

We will see how to display the logged in user Image on the home page and in the menu bar.

Step 8: Display user image in the home page.

For displaying this, we create a FileContentResult Method to display the image on user home and on menu bar.

Create FileContentResult method in Home controller as UserPhotos are used to display the image in home page and on Menu bar.

 
 
In Home Controller, we create a method named as UserPhotos and return the image to View page for the user profile display.

In this method, we check for Authenticated (Logged in) users. If the user is not logged In to our Web Application then I will display his default image as “?”, as shown below. Here, we display the image both at top menu and on home page.

 
 
If the user is authenticated and successfully logged in to our system then we display the logged in user profile picture on the home page, as shown below:
 
 
 
This is the complete code to check the Authenticated user and return the valid user’s image to our View page .This is the method that we created in our Home Controller. 
  1. public FileContentResult UserPhotos()    
  2. {    
  3.     if (User.Identity.IsAuthenticated)    
  4.     {    
  5.     String    userId = User.Identity.GetUserId();    
  6.   
  7.     if (userId == null)    
  8.         {    
  9.             string fileName = HttpContext.Server.MapPath(@"~/Images/noImg.png");    
  10.   
  11.             byte[] imageData = null;    
  12.             FileInfo fileInfo = new FileInfo(fileName);    
  13.             long imageFileLength = fileInfo.Length;    
  14.             FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);    
  15.             BinaryReader br = new BinaryReader(fs);    
  16.             imageData = br.ReadBytes((int)imageFileLength);    
  17.                 
  18.             return File(imageData, "image/png");    
  19.   
  20.         }    
  21.       // to get the user details to load user Image    
  22.         var bdUsers = HttpContext.GetOwinContext().Get<ApplicationDbContext>();    
  23.     var userImage = bdUsers.Users.Where(x => x.Id == userId).FirstOrDefault();    
  24.   
  25.     return new FileContentResult(userImage.UserPhoto, "image/jpeg");    
  26.     }    
  27.     else    
  28.     {    
  29.         string fileName = HttpContext.Server.MapPath(@"~/Images/noImg.png");    
  30.   
  31.         byte[] imageData = null;    
  32.         FileInfo fileInfo = new FileInfo(fileName);    
  33.         long imageFileLength = fileInfo.Length;    
  34.         FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);    
  35.         BinaryReader br = new BinaryReader(fs);    
  36.         imageData = br.ReadBytes((int)imageFileLength);                     
  37.         return File(imageData, "image/png");    
  38.            
  39.     }    
  40. }  
Step 9: MVC View Part.

Home view Page:

 
 In Home Index View, we write the code shown below to display our logged in users profile picture. 
  1. <h1>Shanu Profile Image ..  
  2.       
  3.      <img src="@Url.Action("UserPhotos", "Home" )"  style="width:160px;height:160px; background: #FFFFFF;    
  4.     margin: auto;  
  5.     -moz-border-radius: 60px;  
  6.     border-radius: 100px;  
  7.     padding: 6px;  
  8.     box-shadow: 0px 0px 20px #888;" />  
  9. </h1>  
 _Layout.cshtml

To display our logged in user profile picture to be displayed at the top of our page we write the below code in _Layout.cshtml 

  1. <div class="navbar-collapse collapse">    
  2.     <ul class="nav navbar-nav">    
  3.         <li>     
  4.             <img src="@Url.Action("UserPhotos", "Home" )" height="48" width="48" />    
  5.           
  6.         </li>    
  7.         <li>@Html.ActionLink("Home""Index""Home")</li>    
  8.         <li>@Html.ActionLink("About""About""Home")</li>    
  9.         <li>@Html.ActionLink("Contact""Contact""Home")</li>    
  10.     </ul>    
  11.     @Html.Partial("_LoginPartial")    
  12. </div>     
Step 10: Run the Application.

So now we have completed both upload and display part. Let’s  run our application and register new user with image and check for output.