Role-Based Menus in MVC

Role-Based Menus in MVC

In this article, I am going to discuss how to implement Role-Based Menus in MVC Application. I strongly recommended you to reads our previous two articles before proceeding to this article as it is a continuation part of our previous two articles. In our previous two articles, we discussed how to implement Forms Authentication in MVC and how to implement Role-Based Authentication in MVC application.

Business Requirement:

Our business requirement is we need to display Menus based on the Roles provided to the user. In our previous article, we created three different types of roles such as Admin, User, and Customer, and then assigned these to different types of users.

The Employee Controller Contains 4 views such as Index, Details, Create, Update and Delete. Our requirement is we need to show all menus or links to the users whose role is Admin. Along the same line, we need to show the Create and Index and Details menus or link to the users whose role is User. The users having the role Customer can only see the Index and Details view.

Let us see how to implement this:

First of all, modify the Controller class as shown below. Here we are applying Roles to individual action methods. This is important from the security point of view. This is because sometimes we may directly access the views using some tools like Postman and Fiddler.

Role Based Menus in MVC

Modifying the _Layout.cshtml file:

Please modify the layout file as shown below to implement role-based menus.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Employee Portal", "Index", "Employees", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    
                    @if (User.Identity.IsAuthenticated)
                    {
                        <li>@Html.ActionLink("Get List", "Index", "Employees")</li>

                        if (User.IsInRole("Admin") || User.IsInRole("User"))
                        {
                            <li>@Html.ActionLink("Create", "Create", "Employees")</li>
                        }
                        <li><a>Hello - @User.Identity.Name</a></li>
                        <li>@Html.ActionLink("Logout", "Logout", "Accounts")</li>
                    }
                    else
                    {
                        <li>@Html.ActionLink("Login", "Login", "Accounts")</li>
                    }
                </ul>
            </div>
        </div>
    </div>

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>

Note: The User.IsInRole() method takes the Role name as input and returns true or false based on the logged-in user role.

Modifying the Index View:

Let us do the same thing within the index view where we show the buttons for details, edit and delete. So, modify the Index view of Employees controller as shown below.

@model IEnumerable<SecurityDemoMVC.Models.Employee>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Designation)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Salary)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Designation)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Salary)
        </td>
        <td>
            @if (User.IsInRole("Admin"))
            {
                @Html.ActionLink("Edit", "Edit", new { id = item.ID }) <text>|</text>
                @Html.ActionLink("Delete", "Delete", new { id = item.ID }) <text>|</text>
            }
           
            @Html.ActionLink("Details", "Details", new { id=item.ID })
        </td>
    </tr>
}

</table>

That’s it. We are done with our implementation. Now run the application and see everything is working as expected.

In the next article, I am going to discuss one of the most important concepts i.e. ASP.NET Identity in ASP.NET MVC Application. Here, in this article, I try to explain how to implement Role-Based Menus in ASP.NET MVC application. I hope you understood how to implement Role-based menus.