2016-06-10 3 views
0

여기 내가 달성하려고하는 것입니다. navbar의 특정 옵션은 사용자가 데이터베이스에 "부하 직원"이있는 경우에만 사용할 수 있어야합니다.MVC 세션 전역 변수

그래서, 네비게이션 바에서 내가 가진 : enter image description here

승인은 일부 사용자에 대해 숨겨진, 그러나 다른 사람에게 제공되어야한다. 이용 가능해야하는 사용자는 A) 관리자 또는 B) DB 테이블에 보조 식별 기호가 있습니다

따라서 "A"와 마찬가지로 매우 간단합니다. 나는했다 :

    @if (User.IsInRole("Supervisor")) 
        { 
         <li>@Html.ActionLink("Approvals", "Index", "Approval")</li> 
        } 

"B"의 경우 세션을 사용하는 것이 좋습니다. 잘 됐네. 그래서 나는 질문에 : 어떻게 내가 DB를 요청하고 Session [ "HasSubordinates"]에 할당하여이 검사를 할 수 있습니까? 내가 뭘하려

    @if (User.IsInRole("Supervisor") || (bool)Session["HasSubordinates"]) 
        { 
         <li>@Html.ActionLink("Approvals", "Index", "Approval")</li> 
        } 

는 것이 었습니다 : 모든 단일 컨트롤러에 대한

Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0; 

,하지만 때로는 내가 널 포인터를 얻을 수 있기 때문에 그것은 잘 작동하지 않았고 절대적으로 쓰레기 보인다.

일부 (또는 대부분)에게는 사소한 질문처럼 들리 겠지만 실제로 붙어서 정말 도움이됩니다.

+1

서비스가 만료되지 않는 한 한 번만 전화하면됩니다. 로그인 방법으로 전화 할 수 있습니다. –

+0

안녕하세요. Stephen 님, 사용자가 창을 닫았지만 로그 아웃하지 않으면 어떻게됩니까? 로그인이 트리거되지 않으므로 세션이 비어있게됩니다. 맞습니까? – AuroMetal

+0

UserIdentity를 확장하고 데이터베이스 호출 결과를 캐시하므로 _Layout이 실행될 때마다 호출하지 않습니다. –

답변

1

코드를 보면 부하 직원을 얻는 일은 한 번만 발생해야합니다. 로그인 방법 :보기에 지금

public class IPrincipalExtensions 
{ 
    public bool HasSubordinates(this IPrincipal user) 
    { 
    return Session != null && Session["HasSubordinates"] != null && Session["HasSubordinates"] > 0; 
    } 
} 

:

Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0; 

는 IPrincipal을 확장하는 새로운 클래스를 작성 메모리에서 작성

@if (User.IsInRole("Supervisor") || User.HasSubordinates()) 
{ 
} 

는, 무언가를 떠난 수 있습니다, 그러나 이것은 가장 깨끗해야합니다.

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를 부분 뷰를 작성하고 당신이 좋아하지만 당신의 탐색을 렌더링 할 뷰 모델의 속성을 사용합니다.

원하는 경우 하위 작업에서 출력 캐싱을 사용할 수도 있으므로 사용자 당 한 번만 평가됩니다. 당신이 다음 단지와 자녀의 행동을 장식 할 수 있습니다, 그와

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(); 
} 

:이 사용자가 캐시를 변화 할 내장 방법은 없습니다, 그래서 첫째, 당신의 Global.asax에 다음 메서드를 재정의해야합니다 :

[OutputCache(Duration = 3600, VaryByCustom = "User")]