Introduction
In order to give each user a customized navigation experience, this article shows how to save and display dynamic menus on the layout page using session management in ASP.NET Core 6.
1. Enable Session in Program.cs
AddSession and UseSession methods must be added to the pipeline in order to configure the session in the Program.cs file in ASP.NET Core 6. The code to enable the session is as follows.
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
});
builder.Services.AddSession();
2. Define the Menu Model
To show the menu's structure, you require a model. This is a simple model that includes Submodule and ModuleSubmoduleRolePermission.
public class ModuleSubmoduleRolePermission
{
public int ModuleId { get; set; }
public string ModuleName { get; set; }
public string Action { get; set; }
public bool IsChecked { get; set; }
public List<SubmodulePermission> Submodules { get; set; }
}
public class SubmodulePermission
{
public int? SubmoduleId { get; set; }
public string SubmoduleName { get; set; }
public string Controller { get; set; }
public string subAction { get; set; }
public string RoleName { get; set; }
public int? RoleId { get; set; }
public bool IsChecked { get; set; }
}
3. Store Menu Data in Session
Serialize the menu data in your controller and save it in the session. This is an example of an action method.
[HttpPost]
public async Task<ActionResult> Login(LoginModel model)
{
if (ModelState.IsValid)
{
var response = await _authService.LoginAsync(model);
if (response.Success == true) // Assuming "1" indicates success
{
var token = response.Token;
Response.Cookies.Append("authToken", token, new CookieOptions
{
HttpOnly = true, // Prevent JavaScript access to the cookie
Secure = true, // Only send cookie over HTTPS
SameSite = SameSiteMode.Strict // Prevent CSRF attacks
});
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(token) as JwtSecurityToken;
var userRole = jsonToken?.Claims.FirstOrDefault(c => c.Type == "role")?.Value;
var Module = await _authService.GetModulesByRoleAsync(token,userRole);
HttpContext.Session.SetString("Modules", JsonConvert.SerializeObject(Module));
// If login is successful, redirect to another action (e.g., Dashboard)
return RedirectToAction("Dashboard", "Dashboard");
}
else
{
// If login failed, show the error message from StatusDesc
ViewBag.ErrorMessage= response.Message;
}
}
// If we got this far, something failed; redisplay the form
return View(model);
}
4. Retrieve and Display Menu in _Layout.cshtml
You can dynamically render the menu and access the session data on the layout page. To retrieve session values, use IHttpContextAccessor; to deserialize the data, use JsonConvert.
@inject IHttpContextAccessor HttpContextAccessor
@using ModelsLibrary.ADOModel
@using Newtonsoft.Json
@{
var modulesJson = HttpContextAccessor.HttpContext?.Session.GetString("Modules");
var UserName = HttpContextAccessor.HttpContext?.Session.GetString("username");
List<ModuleSubmoduleRolePermission> modules = new();
if (!string.IsNullOrEmpty(modulesJson))
{
modules = JsonConvert.DeserializeObject<List<ModuleSubmoduleRolePermission>>(modulesJson);
}
}
5. Retrieve Menu Data
<div class="sidebar-nav">
<!--navigation-->
<ul class="metismenu" id="sidenav">
@if (modules != null)
{
@foreach (var module in modules)
{
<li>
<a href="@(string.IsNullOrEmpty(module.Action) ? "javascript:;" : GetUrl(module.Action))"
class="@(module.Submodules != null ? "has-arrow" : "")">
<div class="parent-icon">
<i class="material-icons-outlined">@GetIconForModule(module.ModuleName)</i>
</div>
<div class="menu-title">@module.ModuleName</div>
</a>
@if (module.Submodules != null)
{
<ul>
@foreach (var submodule in module.Submodules)
{
<li>
<a href="@GetUrl(submodule.subAction)">
<i class="material-icons-outlined">arrow_right</i>
@submodule.SubmoduleName
</a>
</li>
}
</ul>
}
</li>
}
}
else
{
<p>No modules available</p>
}
</ul>
<!--end navigation-->
</div>
Output
Conclusion
The user experience in web applications can be enhanced by using this method to dynamically create a customized navigation menu based on session data in ASP.NET Core 6. You can do this by storing menu items in the session and using them in your layout to render dynamic menus that reflect the user's role or context.