Navigation Menus in ASP.NET Core MVC

Navigation-Menus in ASP.NET Core MVC Application

In this article, I will discuss How to Create Responsive Navigation-Menus in ASP.NET Core MVC Applications using Bootstrap and jQuery. Please read our previous article discussing the Environment Tag Helper in ASP.NET Core MVC Web Application.

Responsive Navigation-Menus in ASP.NET Core MVC

Creating responsive navigation menus in ASP.NET Core MVC involves using CSS and JavaScript alongside your Razor views. In this article, I will show you how to implement a responsive navigation menu adaptable to various screen sizes using Bootstrap, which is a popular framework for building responsive websites. ASP.NET Core MVC projects created with the web application template include Bootstrap by default.

Business Requirement:

When we open our web application on large-screen devices like desktops and tablets, we want the navigation menus to look like the image below. Here, you can see the menus List, Create, About, and Contact, which are visible.

Large Device Navigation Menus in ASP.NET Core Application

But when we open our website on a small screen device like a mobile, we want to show the navigation menus like the one below. Here, you can see the menus List, Create, About, and Contact are not visible; instead, the hamburger menu (three horizontal lines) is visible, and once we click on the three horizontal lines, it will display all the menus.

Small Device Navigation Menus in ASP.NET Core Application

Let us Proceed and see How we can Implement the above using the ASP.NET Core MVC Application.

Creating a New ASP.NET Core MVC Application:

First, we create a new ASP.NET Core Application using the Model-View-Controller Project Template named FirstCoreMVCApplication. Once we create the project, we must add the required Bootstrap and jQuery files.

Adding Bootstrap and jQuery files:

The most important point you need to remember is that Bootstrap depends on jQuery. So, we need to download both Bootstrap and jQuery into our application. Here, we will use a tool called Library Manager (LibMan) to download the required Bootstrap and jQuery files.

So, please follow the steps below to install Bootstrap for your application.

  1. Right-click on the “Project Name” in the Solution Explorer and then select Add > Client-Side Library, which will open the “Add Client-Side Library” Window.
  2. Leave the default provider as it is, which is “cdnjs” in this case. The other providers are filesystem, jsdelivr, and unpkg.
  3. In the “Library” text box, type “twitter-bootstrap“. You can also get intelligence support once you start typing. Once you select the matching entry, it tries installing the latest Bootstrap version. Here, we are installing the latest version of Bootstrap, i.e. (twitter-bootstrap@5.3.0) at this point. While you are reading this article, the latest version might be updated.
  4. There are two radio buttons to select whether to include “All library files” or “Choose Specific files“. Here, I am selecting the “All library files” radio button.
  5. In the “Target Location” text box, specify the folder location where you want the library files to be installed. By default, the static files are only served from the wwwroot folder. I am going with the default location, i.e., “wwwroot/lib/twitter-bootstrap/”.
  6. Finally, click the “Install” button, as shown in the image below.

How to Install Bootstrap in ASP.NET Core Using Library Manager

Once it is successfully installed, you will find two things: the libman.json file and the required bootstrap files, as shown in the image below.

Installing Bootstrap in ASP.NET Core MVC

In the same way, you can install jQuery using Libary Manager. The other option to install the jQuery file is to open the libman.json file and then copy and paste the following code into it. 

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "library": "twitter-bootstrap@5.3.0",
      "destination": "wwwroot/lib/twitter-bootstrap/"
    },
    {
      "provider": "cdnjs",
      "library": "jquery@3.7.0",
      "destination": "wwwroot/lib/jquery/"
    }
  ]
}

As you can see in the above code, here we are adding jquery@3.7.0. It will automatically install the required jQuery files inside the lib folder.

Adding images Folder inside the wwwroot folder:

Add a folder called images with the wwwroot folder and then paste two different images with the names Logo.png and Student.png, as shown in the image below.

Logo and Student Image

Adding Custom CSS:

By default, the ASP.NET Core Model-View-Controller template creates a folder with the name CSS within the wwwroot folder. If not added, then please add a folder with the name CSS within the wwwroot folder and then add a CSS file with the name MyCustomStyleSheet.css. Once you create the MyCustomStyleSheet.css file, copy and paste the following code.

.btn {
    width: 80px;
}

With the above changes in place, your wwwroot folder should look as shown below.

Responsive Navigation Menus in ASP.NET Core Applications using Bootstrap with Examples

Modifying _ViewImports.cshtml file:

Please modify the _ViewImports.cshtml file as shown below. We are adding the HTML Tag Helper here to use the Tag Helper throughout the application views. By default, you will see the following code as well.

@using FirstCoreMVCApplication
@using FirstCoreMVCApplication.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Modifying _Layout.cshtml file:

Use the Bootstrap Navbar component to create your navigation menu. Bootstrap’s Navbar automatically becomes responsive and will toggle between a horizontal menu and a hamburger menu on smaller screens.

Please modify the _Layout.cshtml file, which is present inside the Views => Shared folder, as shown below. In the head section, we refer to the files MyCustomStyleSheet.css, bootstrap.css, query.js, and bootstrap.js. The navbar-toggler button is a responsive component that will appear on smaller screen sizes. When clicked, it toggles the visibility of the navigation menu items. 

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/css/MyCustomStyleSheet.css" rel="stylesheet" />
    <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
    <script src="~/lib/jquery/jquery.js"></script>
    <script src="~/lib/twitter-bootstrap/js/bootstrap.js"></script>
</head>
<body>

    <div class="container">
        <nav style="margin-top:15px" class="navbar navbar-expand-sm bg-dark navbar-dark">
            <div class="container-fluid">
                <a style="margin-left:5px" class="navbar-brand" asp-controller="home" asp-action="index">
                    <img src="~/images/Logo.png" width="50" height="50">
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link" asp-controller="home" asp-action="index">List</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" asp-controller="home" asp-action="create">Create</a>
                        </li>
                        <li>
                            <a class="nav-link" asp-controller="home" asp-action="about">About</a>
                        </li>
                        <li>
                            <a class="nav-link" asp-controller="home" asp-action="contact">Contact</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>

        <div>
            @RenderBody()
        </div>
    </div>

</body>
</html>
Explanation of the above Code:
Navigation Menu
<nav style="margin-top:15px" class="navbar navbar-expand-sm bg-dark navbar-dark">:

A Bootstrap-styled navigation bar, dark-themed. It’s set to expand on small devices.

<a class="navbar-brand" asp-controller="home" asp-action="index">
    <img src="~/images/Logo.png" width="50" height="50">
</a>

When clicked, a link that acts as the website’s brand logo navigates to the Home Controller’s Index action. The ASP.NET Core MVC uses the asp-controller and asp-action tags for routing.

<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
        aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
</button>

This is a button for toggling the navigation bar on small screens. It uses Bootstrap’s collapse plugin to control the visibility of the navigation links.

<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">

This section contains the navigation links. Due to the d-sm-inline-flex class, it collapses on small screens and becomes horizontal on larger screens.

<ul class="navbar-nav flex-grow-1">
    <li class="nav-item">
        <a class="nav-link" asp-controller="home" asp-action="index">List</a>
    </li>
    <!-- Other nav items -->
</ul>

The list of navigation links. Each tag uses asp-controller and asp-action attributes for routing to different application parts (e.g., List, Create, About, Contact).

Main Content Area
<div>
    @RenderBody()
</div>

@RenderBody() is a placeholder where the content of individual views that use this layout will be rendered. Each page’s specific content will appear here.

Note: The jQuery reference must be loaded before loading the Bootstrap JavaScript file for the navbar toggle button to work on a small-screen device. If you change the order, the navbar toggle button does not work as expected.

Creating Models:

First, we need to create two enums to store the Gender and Branch of a student. So, create two classes within the Models folder named Gender.cs and Branch.cs.

Branch.cs

Open the Branch.cs class file and copy and paste the following code. As you can see, we have created the Branch enum with four named constants, i.e., None, CSE, ETC, and Mech.

namespace FirstCoreMVCApplication.Models
{
    public enum Branch
    {
        None,
        CSE,
        ETC,
        Mech
    }
}
Gender.cs

Next, open the Gender.cs class file and copy and paste the following code. As you can see, we have created the Gender enum with two named constants, i.e., Male and Female.

namespace FirstCoreMVCApplication.Models
{
    public enum Gender
    {
        Male,
        Female
    }
}
Student Model:

We want to display the student information on the web page. So, create a class file named Student.cs within the Models folder and copy and paste the following code.

using System.Collections.Generic;
namespace FirstCoreMVCApplication.Models
{
    public class Student
    {
        public int StudentId { get; set; }
        public string? Name { get; set; }
        public string? Email { get; set; }
        public Branch? Branch { get; set; }
        public Gender? Gender { get; set; }
        public string? Address { get; set; }
    }
}
Modifying Home Controller:

Next, modify the Home Controller as shown below. As you can see in the code below, we have added two action methods. The Index action method will return all the students, while the Details action takes the student ID and returns that student’s information.

using FirstCoreMVCApplication.Models;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;

namespace FirstCoreMVCApplication.Controllers
{
    public class HomeController : Controller
    {
        //Create a Variable to Hold List of Students
        //This is going to be our data source
        private List<Student> listStudents = new List<Student>();
        public HomeController()
        {
            //Within the Constructor we are Initializing listStudents variable
            //In Real-Time, we will get the data from the database
            listStudents = new List<Student>()
            {
               new Student() { StudentId = 101, Name = "James", Branch = Branch.CSE, Gender = Gender.Male, Address = "A1-2018", Email = "James@g.com" },
               new Student() { StudentId = 102, Name = "Priyanka", Branch = Branch.ETC, Gender = Gender.Female, Address = "A1-2019", Email = "Priyanka@g.com" },
               new Student() { StudentId = 103, Name = "David", Branch = Branch.CSE, Gender = Gender.Male, Address = "A1-2020", Email = "David@g.com" },
               new Student() { StudentId = 104, Name = "Pranaya", Branch = Branch.Mech, Gender = Gender.Male, Address = "A1-2021", Email = "Pranaya@g.com" }
            };
        }
        public ViewResult Index()
        {
            //returning all the students
            return View(listStudents);
        }

        public ViewResult Details(int Id)
        {
            //returning the student based on the Student Id
            var studentDetails = listStudents.FirstOrDefault(std => std.StudentId == Id);
            return View(studentDetails);
        }
    }
}
Modifying Index.cshtml file:

Please modify the Index view, which is present inside the Home folder, as shown below. Notice how the buttons (View, Edit, and Delete) are attached to each other. Use the Bootstrap margin classes (m-1, m-2, etc.) to include the margin between these buttons. In the class name, “m” stands for margin, and the numbers 1, 2, 3, etc., are the size of the space you want between the buttons. In this view, List<Student> is the model, and using a for each loop, we are accessing all the students. Further, if you notice, we have used Tag Helper to generate the link for the View button.

@model List<Student>
@{
    ViewBag.Title = "Student List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row">
    @foreach (var student in Model)
    {
        <div class="col-sm-3">
            <div class="card m-3">
                <div class="card-header">
                    <h3>@student.Name</h3>
                </div>
                <div class="card-body">
                    <img class="card-img-top" src="~/images/Student.png" />
                </div>
                <div class="card-footer text-center">
                    <a asp-controller="home" asp-action="details"
                       asp-route-id="@student.StudentId" class="btn btn-primary m-1">View</a>
                    <a href="#" class="btn btn-primary m-1">Edit</a>
                    <a href="#" class="btn btn-danger m-1">Delete</a>
                </div>
            </div>
        </div>
    }
</div>
Creating Detail.cshtml file:

Please create a view named Details.cshtml within the Views/Home folder and copy and paste the following code into it. In this view, the Student will be the model, and we can access the student model properties using the @Model object.

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

<div class="row justify-content-center m-3">
    <div class="col-sm-8">
        <div class="card">
            <div class="card-header">
                <h1>@Model?.Name</h1>
            </div>

            <div class="card-body text-center">
                <img class="card-img-top" src="~/images/Student.png" />
                <h4>Studnet ID : @Model?.StudentId</h4>
                <h4>Email : @Model?.Email</h4>
                <h4>Branch : @Model?.Branch</h4>
                <h4>Gender : @Model?.Gender</h4>
                <h4>Address : @Model?.Address</h4>
            </div>
            <div class="card-footer text-center">
                <a href="#" class="btn btn-primary">Back</a>
                <a href="#" class="btn btn-primary">Edit</a>
                <a href="#" class="btn btn-danger">Delete</a>
            </div>
        </div>
    </div>
</div>
Program.cs Class:

Please modify the Program class code as follows. Actually, we are not making any changes in the Main method of the Program class as we have created the Project using Model-View-Controller, which by default includes all the required MVC services and middleware in the request processing pipeline.

namespace FirstCoreMVCApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            app.Run();
        }
    }
}

Now, run your application and resize the browser window, or use a mobile device to see the responsive navigation menu in action. On smaller screens, the menu items should collapse into a hamburger menu (three horizontal lines). When you click the hamburger menu, it will show the menu items in a dropdown fashion.

In the next article, I will discuss Form Tag Helpers in the ASP.NET Core MVC Application with Examples. In this article, I explain how to create Responsive Navigation Menus in ASP.NET Core MVC Applications using Bootstrap with Examples. I hope you enjoy this article.

2 thoughts on “Navigation Menus in ASP.NET Core MVC”

  1. blank

    Hello,

    i tried this implementing but facing small issue. I followed all steps ui is coming correctly but anchore tag helper not rendering its showing as taghelper.
    i modified removing ; in _ViewImports.cshtml then tag helpers working properly. but UI is not working properly.

    @using AspNetCore_Menu.Models
    @using AspNetCore_Menu.Models.DataTypes
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

    if ; is kept for each like @using AspNetCore_Menu.Models; then ui is properly coming.

    startup.cs
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddMvc(options => options.EnableEndpointRouting = false);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseStaticFiles();

    app.UseRouting();

    app.UseMvcWithDefaultRoute();
    }

    Any suggestions.

    and thanks for nice article its easy to understand.

  2. blank

    Can you update the page to include the img files you referred to (Logo.png and Student.png)? For adding bootstrap and JQuery files, is it the same as adding the client package of twitter-bootstrap you mentioned earlier? Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *