Hello everyone I am trying to check what Role my user is in with the default setup.
I thought I would only need 'User.IsInRole("User")' for in my View but its not so easy.
I want to display certain links depending on the role for the user.
Here is what I have and I tried a few different options.
I have the default setup database and some added tables that dont matter for this part.
Request.IsAuthenticated works for login.
I tried user.isinrole and request.isauthenticated but nether worked for this instance with my view
#if (Request.IsAuthenticated)
{
<li class="nav-item">
<a class="nav-link" href="#">Assign Roles</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">View Roles</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Reset Password</a>
</li>
} else if (Request.IsAuthenticated && User.IsInRole("User"))
{
<li class="nav-item">
<a class="nav-link" href="#">user Else clause</a>
</li>
} else if (Request.IsAuthenticated && User.IsInRole("Guest"))
{
<li class="nav-item">
<a class="nav-link" href="#">guest Else clause</a>
</li>
} else
{
<li class="nav-item">
<a class="nav-link" href="#">else else!! Else clause</a>
</li>
}
The 'else' works when no user is logged in.
You can add extension method for Principal like this
public static class PrincipalExtensions
{
public static bool IsInAllRoles(this IPrincipal principal, params string[] roles)
{
return roles.All(r => principal.IsInRole(r));
}
public static bool IsInAnyRoles(this IPrincipal principal, params string[] roles)
{
return roles.Any(r => principal.IsInRole(r));
}
}
And use
// user must be assign to all of the roles
if(User.IsInAllRoles("Admin","Manager","YetOtherRole"))
{
// do something
}
Read more at Usage of User.IsInRole() in a View
This is what I ended up doing to for my solution
#if (User.IsInRole("User"))
{
<li class="nav-item">
<a class="nav-link" href="#">user Else clause</a>
</li>
}
#if (User.IsInRole("Guest"))
{
<li class="nav-item">
<a class="nav-link" href="#">guest Else clause</a>
</li>
}
Related
I'm having a problem with the code, the program logs in and out
I have three controllers for each type of user, when I log in the program logs in but the presentation is as if they were all from the Socio table.
I already checked the tables and don't have the same data and I checked the layout of the views for each type of user and everything is fine.
Can someone help me fix this please?
The login method is in the controller home, and this is the code:
public IActionResult Login(string user, string password, string? ReturnUrl)
{
SHA512 sha512 = SHA512Managed.Create();
byte[] bytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
string passHash = Convert.ToBase64String(bytes);
Socios socio = _context.Socios.Include(s => s.Gerir).Include(s => s.Mensagem).Include(s => s.Participa).Include(s => s.PersonalTrainer).Include(s => s.Peso).Include(s => s.PlanosExercicios).FirstOrDefault(s => s.NomeUtilizador == user && s.Password == password);
if (socio != null)
{
HttpContext.Session.SetString("Nome", socio.NomeUtilizador);
HttpContext.Session.SetInt32("UserId", socio.Idsocio);
HttpContext.Session.SetString("Perfil", "Socio");
}
Professores prof = _context.Professores.Include(p => p.MapaAulasGrupo).Include(p => p.Mensagem).Include(p => p.Peso).Include(s => s.PersonalTrainer).Include(p => p.PlanosExercicios).FirstOrDefault(p => p.Nome == user && p.Password == password);
if (prof != null)
{
HttpContext.Session.SetString("Nome", prof.Nome);
HttpContext.Session.SetInt32("UserId", prof.Idprofessor);
HttpContext.Session.SetString("Perfil", "Professor");
}
Administrador admin = _context.Administrador.Include(a => a.Gerir).SingleOrDefault(a => a.Nome == user && a.Password == password);
if (admin != null)
{
HttpContext.Session.SetString("Nome", admin.Nome);
HttpContext.Session.SetInt32("UserId", admin.Idadministrador);
HttpContext.Session.SetString("Perfil", "Administrador");
}
if (String.IsNullOrEmpty(ReturnUrl))
{
//ModelState.AddModelError("","Utilizador inexistente na base de dados!");
//TempData["mensagemErro"] = "Utilizador inexistente na base de dados!";
//return View("NaoEncontrado","Socios");
return LocalRedirect("/");
}
else
{
return LocalRedirect(ReturnUrl);
}
}
In the layout I have to differentiate the type of logins, presenting views corresponding to each controller
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index"> </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-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 flex-sm-row-reverse">
<ul class="navbar-nav">
#if (SociosController.estaAutenticado(Context))
{
<li class="nav-item">
<a class="nav-link text-white" asp-controller="Socios" asp-action="PerfilSocio">Meu perfil</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-controller="Socios" asp-action="ListarProfessores">Professores</a>
</li>
<li class="nav-item">
<p class="nav-link text-white">Bem-vindo, #Context.Session.GetString("Nome")</p>
</li>
<li class="nav-item">
<form class="form-inline" asp-controller="Home" asp-action="Logout">
<button type="submit" class="nav-link btn btn-link text-white">Sair</button>
</form>
</li>
}
else if (ProfessoresController.estaAutenticado(Context))
{
<li class="nav-item">
<a class="nav-link text-white" asp-controller="Professores" asp-action="Perfil">Meu perfil</a>
</li>
<li class="nav-item">
<p class="nav-link text-white">Bem-vindo, #Context.Session.GetString("Nome")</p>
</li>
<li class="nav-item">
<form class="form-inline" asp-controller="Home" asp-action="Logout">
<button type="submit" class="nav-link btn btn-link text-white">Sair</button>
</form>
</li>
}
else if (AdministradoresController.estaAutenticado(Context))
{
<li class="nav-item">
<a class="nav-link text-white" asp-controller="Administradores" asp-action="Perfil">Meu perfil</a>
</li>
<li class="nav-item">
<p class="nav-link text-white">Bem-vindo, #Context.Session.GetString("Nome")</p>
</li>
<li class="nav-item">
<form class="form-inline" asp-controller="Home" asp-action="Logout">
<button type="submit" class="nav-link btn btn-link text-white">Sair</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-white" asp-controller="Home" asp-action="Login">Entrar </a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Registo">Registar</a>
</li>
}
</ul>
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Index">Pagina Inicial</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Info">Sobre nós</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="AulasDeGrupo">Aulas de Grupo</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
The function that calls in the layout "estaAutenticado"
is found in the Controllers of each type of user and this is the code:
public static bool estaAutenticado(HttpContext contexto)
{
if (contexto.Session.GetInt32("UserId") != null)
return true;
else
return false;
}
Can someone help me fix this? I don’t understand why he considers all users I log in as a Partner, even if they’re from the Teacher or Administrator tables.
The issue is you set the same Session-key UserId for each type of user , you should make the modification like below:
Login method
Socios socio = _context.Socios.Include(s => s.Gerir).Include(s => s.Mensagem).Include(s => s.Participa).Include(s => s.PersonalTrainer).Include(s => s.Peso).Include(s => s.PlanosExercicios).FirstOrDefault(s => s.NomeUtilizador == user && s.Password == password);
if (socio != null)
{
HttpContext.Session.SetString("Nome", socio.NomeUtilizador);
HttpContext.Session.SetInt32("UserId", socio.Idsocio);
HttpContext.Session.SetString("Perfil", "Socio");
}
Professores prof = _context.Professores.Include(p => p.MapaAulasGrupo).Include(p => p.Mensagem).Include(p => p.Peso).Include(s => s.PersonalTrainer).Include(p => p.PlanosExercicios).FirstOrDefault(p => p.Nome == user && p.Password == password);
if (prof != null)
{
HttpContext.Session.SetString("Nome", prof.Nome);
//set ProfessorId for Professores
HttpContext.Session.SetInt32("ProfessorId", prof.Idprofessor);
HttpContext.Session.SetString("Perfil", "Professor");
}
Administrador admin = _context.Administrador.Include(a => a.Gerir).SingleOrDefault(a => a.Nome == user && a.Password == password);
if (admin != null)
{
HttpContext.Session.SetString("Nome", admin.Nome);
//set AdminId for Administrador
HttpContext.Session.SetInt32("AdminId", admin.Idadministrador);
HttpContext.Session.SetString("Perfil", "Administrador");
}
estaAutenticado method in each type Controller
//SociosController
public static bool estaAutenticado(HttpContext context)
{
if (context.Session.GetInt32("UserId") != null)
return true;
else
return false;
}
//ProfessoresController
public static bool estaAutenticado(HttpContext context)
{
if (context.Session.GetInt32("ProfessorId") != null)
return true;
else
return false;
}
//AdministradoresController
public static bool estaAutenticado(HttpContext context)
{
if (context.Session.GetInt32("AdminId") != null)
return true;
else
return false;
}
I used this code with bootstrap 3, and it worked correctly, when clicking on the page, it appeared as active, but when switching to bootstrap 4, it no longer calls the active class, when I pass the page number inside the "for"
Any ideias how to resolve that?
<ul class="pagination">
<li class="page-item ">
#{
if (ViewBag.pageNumber> 1)
{
<a class="page-link" href="#Url.Action("Index", "Barcos", new { search= ViewBag.Search, pageNumber= ViewBag.pageNumber- 1 })">before</a>
}
else
{
<a class="page-link" href="#">
before
</a>
}
}
</li>
#{
var page = ViewBag.pageNumber;
for (var i = 1; i <= ViewBag.Count; i++)
{
<li #(page== i ? "class=page-item active" : "")>
<a class="page-link" href="#Url.Action("Index", "Barcos", new {search= ViewBag.Search, pageNumber= i})">#i</a>
</li>
}
}
<li>
#if (ViewBag.pageNumber< ViewBag.count)
{
<a class="page-link" href="#Url.Action("Index", "Barcos", new { Search= ViewBag.Search, pageNumber= ViewBag.pageNumber+ 1 })">Next</a>
}
else
{
<a class="page-link disabled" href="#">
Before
</a>
}
</li>
</ul>
You need class="page-item" on all list items, not just for your current page
Corrected bode below.
#for (var i = 1; i <= ViewBag.Count; i++)
{
var page = ViewBag.pageNumber;
string classes = "page-item";
if (page == i)
{
classes += " active";
}
<li class="#classes">
#Html.ActionLink(i.ToString(), "Index", "Barcos", new { search = ViewBag.Search, pageNumber = i }, new { #class = "page-link" })
</li>
}
This generates the following HTML
<ul class="pagination">
<li class="page-item ">
<a class="page-link" href="/Barcos/Index?pageNumber=1">before</a>
</li>
<li class="page-item">
<a class="page-link" href="/Barcos/Index?pageNumber=1">1</a>
</li>
<li class="page-item active">
<a class="page-link" href="/Barcos/Index?pageNumber=2">2</a>
</li>
<li class="page-item">
<a class="page-link" href="/Barcos/Index?pageNumber=3">3</a>
</li>
<li>
<a class="page-link" href="/Barcos/Index?pageNumber=4">Next</a>
</li>
</ul>
I'm able to make just two level Menu from database How can I make it up to three level or more
I've seen a lot of tutorials but they all are to much of complex
Here is what I've done so far
My Action
public ActionResult SideMenu()
{
ViewBag.MenuLevelTest = Db
.Menus
.Where(menu => menu.ParentId == null)
.ToList();
return PartialView("_SideMenu");
}
My View
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-hover-submenu " data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
#foreach (var menuLevelTest in ViewBag.MenuLevelTest)
{
<li class="nav-item start">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">#menuLevelTest.Name</span>
<span class="arrow"></span>
</a>
#if (menuLevelTest.Menu1.Count > 0)
{
<ul class="sub-menu">
#foreach (var menuLevelTest2 in menuLevelTest.Menu1)
{
<li class="nav-item start ">
<a href="index.html" class="nav-link ">
<i class="icon-bar-chart"></i>
<span class="title">#menuLevelTest2.Name</span>
</a>
</li>
}
</ul>
}
</li>
}
</ul>
I've tried to extend it by doing this but it does not work, what is the easiest way to make this happen
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-hover-submenu " data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
#foreach (var menuLevelTest in ViewBag.MenuLevelTest)
{
<li class="nav-item start">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">#menuLevelTest.Name</span>
<span class="arrow"></span>
</a>
#if (menuLevelTest.Menu1.Count > 0)
{
<ul class="sub-menu">
#foreach (var menuLevelTest2 in menuLevelTest.Menu1)
{
<li class="nav-item">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-bar-chart"></i>
<span class="title">#menuLevelTest2.Name</span>
</a>
#if (menuLevelTest.Menu2.Count > 0)
{
<ul class="sub-menu">
#foreach (var menuLevelTest3 in menuLevelTest.Menu2)
{
<li class="nav-item">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-bar-chart"></i>
<span class="title">#menuLevelTest3.Name</span>
</a>
</li>
}
</ul>
}
</li>
}
</ul>
}
</li>
}
</ul>
This is how I Achieved the three levels
Created a BaseController
got the list of All menus
public BaseController()
{
ViewBag.Menu = MenuList();
}
private IList<Menu> MenuList()
{
var list = Db.Menus.ToList();
return list;
}
Here is my Razor for partial View
#{
List<MisNew.Web.EntityModel.Menu> menuList = ViewBag.Menu;
}
<ul class="menu page-sidebar-menu page-header-fixed page-sidebar-menu-hover-submenu " data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
#foreach (var mp in menuList.Where(p => p.ParentId == null))
{
<li class="#mp.ListCss">
<a href="#" class="#mp.HyperLinkCss">
<i class="#mp.IconCss"></i>
<span class="title">#mp.Name</span>
<span class="arrow"></span>
</a>
#if (menuList.Count(p => p.ParentId == mp.Id) > 0)
{
#:<ul class="sub-menu">
}
#RenderMenuItem(menuList, mp)
#if (menuList.Count(p => p.ParentId == mp.Id) > 0)
{
#:</ul>
}
</li>
}
</ul>
#helper RenderMenuItem(List<MisNew.Web.EntityModel.Menu> menuList, MisNew.Web.EntityModel.Menu mi)
{
foreach (var cp in menuList.Where(p => p.ParentId == mi.Id))
{
#:<li class="#cp.ListCss">
<a href="~/#cp.Url">
<i class="#cp.IconCss"></i>
<span class="title">#cp.Name</span>
<span class="arrow"></span>
</a>
if (menuList.Count(p => p.ParentId == cp.Id) > 0)
{
#:<ul class="sub-menu">
}
#RenderMenuItem(menuList, cp)
if (menuList.Count(p => p.ParentId == cp.Id) > 0)
{
#:</ul>
}
else
{
#:</li>
}
}
}
Currently I have my code for Membership Roles in C# structured like this below
#if (WebApiApplication.CurrentUser.CurrentRole == Role.SysAdmin || WebApiApplication.CurrentUser.CurrentRole == Role.Coordinator)
{
<li id="HomeMenu" class="#Model.GetMenuClass("HomeMenu")"><i class="fa fa-home"></i> Home</li>
<li id="InternsMenu" class="#Model.GetMenuClass("InternsMenu")"><i class="fa fa-user"></i> Interns</li>
<li id="ProjectsMenu" class="#Model.GetMenuClass("ProjectsMenu")"><i class="fa fa-list-alt"></i> Projects</li>
<li id="AssignmentsMenu" class="#Model.GetMenuClass("AssignmentsMenu")"><i class="fa fa-paperclip"></i> Assignments</li>
}
#if (WebApiApplication.CurrentUser.CurrentRole == Role.User )
{
<li id="HomeMenu" class="#Model.GetMenuClass("HomeMenu")"><i class="fa fa-home"></i> Home</li>
<li id="InternsMenu" class="#Model.GetMenuClass("InternsMenu")"><i class="fa fa-user"></i> Interns</li>
<li id="ProjectsMenu" class="#Model.GetMenuClass("ProjectsMenu")"><i class="fa fa-list-alt"></i> Projects</li>
<li id="AssignmentsMenu" class="#Model.GetMenuClass("AssignmentsMenu")"><i class="fa fa-paperclip"></i> Assignments</li>
}
#if (WebApiApplication.CurrentUser.CurrentRole == Role.Intern)
{
<li id="HomeMenu" class="#Model.GetMenuClass("HomeMenu")"><i class="fa fa-home"></i> Home</li>
<li id="TimecardMenu" class="#Model.GetMenuClass("TimecardMenu")"><i class="fa fa-user"></i> Interns</li>
<li id="FeedbackMenu" class="#Model.GetMenuClass("ProjectsMenu")"><i class="fa fa-list-alt"></i> Projects</li>
<li id="SupportMenu" class="#Model.GetMenuClass("SupportMenu")"><i class="fa fa-question-circle"></i> Support</li>
}
What would be a better way to handle Roles logic instead of in Razor View ? Doing it in the C# model?
I think something like this is OK to handle in the View as it handles the display of the menu items in your page.
As others mentioned above in the comments, it is a good idea to define properties in your view model that map to users roles and use that instead.
You could use a switch statement instead and group the options that apply to different roles. For example, I did noticed in your example that roles SysAdmin, Coordinator and User all have the same menu items, all roles have access to the Home menu and only role Intern should see the TimeCard, Feedback and Support menus.
See example below:
<li id="HomeMenu" class="#Model.GetMenuClass("HomeMenu")"><i class="fa fa-home"></i> Home</li>
#switch (WebApiApplication.CurrentUser.CurrentRole)
{
case Role.SysAdmin:
case Role.Coordinator:
case Role.User:
<li id="InternsMenu" class="#Model.GetMenuClass("InternsMenu")"><i class="fa fa-user"></i> Interns</li>
<li id="ProjectsMenu" class="#Model.GetMenuClass("ProjectsMenu")"><i class="fa fa-list-alt"></i> Projects</li>
<li id="AssignmentsMenu" class="#Model.GetMenuClass("AssignmentsMenu")"><i class="fa fa-paperclip"></i> Assignments</li>
break;
case Role.Intern:
<li id="TimecardMenu" class="#Model.GetMenuClass("TimecardMenu")"><i class="fa fa-user"></i> Interns</li>
<li id="FeedbackMenu" class="#Model.GetMenuClass("ProjectsMenu")"><i class="fa fa-list-alt"></i> Projects</li>
<li id="SupportMenu" class="#Model.GetMenuClass("SupportMenu")"><i class="fa fa-question-circle"></i> Support</li>
break;
}
I have the following HTML
<div id='cssmenu'>
<ul>
<li class= 'has-sub'>
<a href=store.aspx?id=dLYTWvt8EsHOq7Ps2wJA9A%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat</span></a>
<ul>
<li class= 'has-sub'>
<a href=store.aspx?id=xEDEzZWDRkX8%2fbXoMX2pSQ%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-2</span></a>
<ul>
<li class= 'active'><a href=store.aspx?id=TxlSRrnSZ6HDgj%2b2ZSxRhg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance -1</span></a></li>
<li class= 'active'><a href=store.aspx?id=Y7JxNAXSuG1T%2f0cpjQXSwA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance - 2</span></a></li>
<li class= 'active'><a href=store.aspx?id=%2fcoJMcJTjWp3%2bPuimR5AhA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-5</span></a></li>
</ul>
</li>
<li class= 'has-sub'>
<a href=store.aspx?id=KC2g4igBzXisbsbKu%2fKrzw%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-3</span></a>
<ul>
<li class= 'active'><a href=store.aspx?id=8DCHnP%2b4KQVYDTGxVt9snQ%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Death -1</span></a></li>
<li class= 'active'><a href=store.aspx?id=nGEm4rbNMQ%2bQfyO44ECmpA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Death - 1</span></a></li>
</ul>
</li>
<li class= 'has-sub'><a href=store.aspx?id=feki%2bXDs66obnO1e2dxHWg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-4</span></a></li>
<li class= 'has-sub'><a href=store.aspx?id=5O394Lww9oxD1vHbIY7LWw%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-6</span></a></li>
</ul>
</li>
<li class= 'active'><a href=store.aspx?id=RIe63RBggHzj76SUwDHKMg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance</span></a></li>
</ul>
</div>
And in reqid
var reqid = "<%=Request["id"]%>";
In reqid I will get urlencoded based on menu selection
My jQuery code here
$(function () {
var str = $("#cssmenu").find('li').find('a').attr('href');
if ($(str).has(reqid)) {
var str2 = $("#cssmenu").find('li').find('a').text();
$('#selectedmenuitem').html(str2);
}
});
If the href attribute encoded url contains selected menu item encodedurl i want to get the matched url .text() to the #selectedmenuitem label id.
I checked with contains, am not getting. Please suggest me what are other possibilities for this.
use indexOf function of Javascript
http://www.w3schools.com/jsref/jsref_indexof.asp
Use following jquery code
$(function () {
var str2= $("#cssmenu").find("li").find("a[href*='" + reqid + "']").text();
$('#selectedmenuitem').html(str2);
});