ProudMonkey

Building Web Application using Entity Framework and MVC 5: Part 4

Just to give you a quick recap, In Part 1, I’ve demonstrated how to create a simple database from scratch, talked about a brief overview of ASP.NET MVC in general, demonstrated how to build a simple data access using the Entity Framework 6, and created a simple implementation of a Signup page in MVC. Part 2 of the series talked about the step-by-step process of creating a basic login page and creating a simple role-based page authorization within the MVC application. Part 3 of the series talked about how to do Fetch, Edit, Update and Delete (FEUD) operations in the application using jQuery and jQuery AJAX.

If you haven't gone through my previous articles, please refer to the following links:

In this series, we will create a page to allow users to modify their profile data. Let’s get started.

Adding the GetUserProfile() Method

To begin with, open “UserManager” class and add the following method below:

public UserProfileView GetUserProfile(int userID) {  
            UserProfileView UPV = new UserProfileView();  
            using (DemoDBEntities db = new DemoDBEntities()) {  
                var user = db.SYSUsers.Find(userID);  
                if (user != null) {  
                    UPV.SYSUserID = user.SYSUserID;  
                    UPV.LoginName = user.LoginName;  
                    UPV.Password = user.PasswordEncryptedText;  

                    var SUP = db.SYSUserProfiles.Find(userID);  
                    if (SUP != null) {  
                        UPV.FirstName = SUP.FirstName;  
                        UPV.LastName = SUP.LastName;  
                        UPV.Gender = SUP.Gender;  
                    }  

                    var SUR = db.SYSUserRoles.Find(userID);  
                    if (SUR != null) {  
                        UPV.LOOKUPRoleID = SUR.LOOKUPRoleID;  
                        UPV.RoleName = SUR.LOOKUPRole.RoleName;  
                        UPV.IsRoleActive = SUR.IsActive;  
                    }  
                }  
            }  
            return UPV;  
}

The method above gets the specific user information from the database by passing the SYSUserID as a parameter. You may have noticed that the method returns a UserProfileView type which holds some properties from different tables.

Adding the EditProfile() Action Method

Now, open “HomeController” class and add the following action methods below:

[Authorize]
public ActionResult EditProfile()  
{
    string loginName = User.Identity.Name;
    UserManager UM = new UserManager();
    UserProfileView UPV = UM.GetUserProfile(UM.GetUserID(loginName));
    return View(UPV);
}


[HttpPost]
[Authorize]
public ActionResult EditProfile(UserProfileView profile)  
{
    if (ModelState.IsValid)
    {
        UserManager UM = new UserManager();
        UM.UpdateUserAccount(profile);

        ViewBag.Status = "Update Sucessful!";
    }
    return View(profile);
}

The code above, is composed of two action methods. The first EditProfile() method will be invoked, once the page is requested and loaded to the browser. What it does is to get the user profile data by calling the GetUserProfile() method and passing the SYSUserID as the parameter. The second is the overload method which will be invoked during POST request, that is when you hit the Button to save the data. What it does is that it first checks for validity of the fields (if they are valid and not empty), then calls the method UpdateUserAccount() and passes the UserProfileView model from the View to that method. If you still remember from my previous article series, the UpdateUserAccount() method is where it executes the actual saving of data to your database.

You may also have noticed that both action methods are decorated with the [Authorize] attribute to ensure that both methods will only be accessible by authenticated users.

Adding the View

The next step is to generate the View for the profile page. To do this, right click on the EditProfile() method and select “Add View”. In the Add View dialog, supply the needed fields as shown in the figure below:

Figure 1: Add View dialog

Take note of the Model class field value. It should be “UserProfileView”. Now, click Add to scaffold the UI for you.

Visual Studio will generate all the controls in the View, based on the fields you defined from your Model (UserProfileView). This means that it will also generate unnecessary fields we don’t want to edit, such as, the LOOKUPRoleID and IsRoleActive. Besides that, we will also need to provide a drop-down list for displaying the Gender field. So, make sure to update the generated HTML markup. It would look like the following:

@model MVC5RealWorld.Models.ViewModel.UserProfileView  

@{  
    ViewBag.Title = "EditProfile";  
    Layout = "~/Views/Shared/_Layout.cshtml";  
}  

<h2>Edit Your Profile</h2>  

@using (Html.BeginForm())  
{  
    @Html.AntiForgeryToken()  

    <div class="form-horizontal">  
        <hr />  
        <span class="alert-success">@ViewBag.Status</span>  
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })  
        @Html.HiddenFor(model => model.SYSUserID)  

        <div class="form-group">  
            @Html.LabelFor(model => model.RoleName, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.DisplayFor(model => model.RoleName)  
                @Html.ValidationMessageFor(model => model.RoleName, "", new { @class = "text-danger" })  
            </div>  
        </div>  

        <div class="form-group">  
            @Html.LabelFor(model => model.LoginName, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.LoginName, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.LoginName, "", new { @class = "text-danger" })  
            </div>  
        </div>  

        <div class="form-group">  
            @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })  
            </div>  
        </div>  

        <div class="form-group">  
            @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })  
            </div>  
        </div>  

        <div class="form-group">  
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })  
            </div>  
        </div>  

        <div class="form-group">  
            @Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.DropDownListFor(model => model.Gender, new List<SelectListItem> {  
                    new SelectListItem { Text="Male", Value="M" },  
                    new SelectListItem { Text="Female", Value="F" }  
                }, new { @class = "form-control" })  
            </div>  
        </div>  

        <div class="form-group">  
            <div class="col-md-offset-2 col-md-10">  
                <input type="submit" value="Save" class="btn btn-default" />  
            </div>  
        </div>  
    </div>  
}  

<div>  
    @Html.ActionLink("Back", "Welcome")  
</div>  

The markup above is a strongly-typed View which renders the UserProfileViewmodel. Now, add the following markup in the “Welcome.cshtml”.

@Html.ActionLink("Edit Profile", "EditProfile", "Home")  

The markup, above, is nothing but a link to the Edit Profile page, so that when you log in, you can easily navigate to your profile page and start modifying data.

Output

Now, try to build your own code and run your application. The output should look similar to the figure below:

Figure 2: The Edit Profile page

After modifying the data

Figure 3: After successful update

It's that simple!

Source Code

Source code for this series can be found here. You can also download it at CodeProject here.