这是我想要实现的目标。仅当用户具有"下属"时,导航栏上的某些选项才可用。在数据库中。
应该为某些用户隐藏审批,但其他人可以使用。对于那些应该可用的用户,用户必须: A)成为主管或者, B)在数据库表中有一个subornidate
因此,对于" A"它很简单。我做了:
@if (User.IsInRole("Supervisor"))
{
<li>@Html.ActionLink("Approvals", "Index", "Approval")</li>
}
对于&#34; B&#34;,我被建议使用Sessions。好吧,太好了。所以我提出了一个问题:如何向数据库发出单个请求并将其分配给会话[&#34; HasSubordinates&#34;]以便我可以进行此检查?
@if (User.IsInRole("Supervisor") || (bool)Session["HasSubordinates"])
{
<li>@Html.ActionLink("Approvals", "Index", "Approval")</li>
}
我尝试的是:
Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
对于每一个控制器,但这并没有很好地工作,因为有时我得到空指针,它看起来绝对垃圾。
我知道这对某些人(或大多数人)来说听起来像是一个微不足道的问题,但我真的被困住了,我真的很感激任何帮助。
答案 0 :(得分:1)
查看您的代码,获取用户下属应该只发生一次。在您的登录方法中:
Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
创建一个新类以扩展IPrincipal:
public class IPrincipalExtensions
{
public bool HasSubordinates(this IPrincipal user)
{
return Session != null && Session["HasSubordinates"] != null && Session["HasSubordinates"] > 0;
}
}
现在,在视图中:
@if (User.IsInRole("Supervisor") || User.HasSubordinates() )
{
}
从记忆中写作,可能会遗漏一些东西,但这应该是最干净的。
答案 1 :(得分:1)
请勿使用此会话。你需要的是一个儿童行动。
[ChildActionOnly]
public ActionResult Nav()
{
var model = new NavViewModel
{
IsSupervisor = User.IsInRole("Supervisor");
HasSubordinates = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
}
return ParialView("_Nav", model);
}
然后,只需创建一个局部视图_Nav.cshtml
,然后利用视图模型上的属性来渲染您喜欢的导航。
如果需要,您甚至可以对子操作使用输出缓存,因此每个用户只评估一次。没有内置的方法来改变用户的缓存,因此首先,您需要在Global.asax中覆盖以下方法:
public override string GetVaryByCustomString(System.Web.HttpContext context, string custom)
{
var args = custom.ToLower().Split(';');
var sb = new StringBuilder();
foreach (var arg in args)
{
switch (arg)
{
case "user":
sb.Append(User.Identity.Name);
break;
case "ajax":
if (context.Request.Headers["X-Requested-With"] != null)
{
// "XMLHttpRequest" will be appended if it's an AJAX request
sb.Append(context.Request.Headers["X-Requested-With"]);
}
break;
default:
continue;
}
}
return sb.ToString();
}
然后,您可以使用以下命令装饰您的子操作:
[OutputCache(Duration = 3600, VaryByCustom = "User")]