2011-09-29 1 views
2

컨트롤러 조치가 처리 된 후에 특정 테스트 조건을 확인하고 사용자에게 투명하게 다른보기로 라우팅하는 (즉, URL을 변경하지 않음) 필터를 만들 수 있습니까?ASP.NET MVC에서 액션 필터를 사용하여 다른 뷰로 라우팅하지만 같은 URL을 사용하려면 어떻게해야합니까?

는 여기에 몇 가지 의사 코드에서 내 추측 일 것입니다 :

이 단락 회로 동작의 실행 것
public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     // If some condition is true 
     // Change the resulting view resolution to XYZ 

     base.OnResultExecuting(filterContext); 
    } 

답변

7
filterContext.Result = new ViewResult 
{ 
    ViewName = "~/Views/SomeController/SomeView.cshtml" 
}; 

.

0

보안 검사를 수행하는 DCIMAuthorize로 ASP.NET MVC 작업 필터의 AuthorizeAttribute을 확장했으며 사용자가 인증되지 않았거나 권한이 부여되지 않은 경우 작업 필터가 거부 된 페이지에 액세스하도록 사용자를 안내합니다.

public class DCIMAuthorize : AuthorizeAttribute 
{ 

    public string BusinessComponent { get; set; } 

    public string Action { get; set; } 
    public bool ResturnJsonResponse { get; set; } 
    public bool Authorize { get; set; } 

    public DCIMAuthorize() 
    { 
     ResturnJsonResponse = true; 
    } 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 

     try 
     { 
      //to check whether user is authenticated 
      if (!httpContext.User.Identity.IsAuthenticated) 
       return false; 
      //to check site level access 
      if (HttpContext.Current.Session["UserSites"] != null) 
      { 
       var allSites = (VList<VSiteList>)HttpContext.Current.Session["UserSites"]; 
       if (allSites.Count <= 0) 
        return false; 
      } 
      else 
       return false; 

      // use Authorize for authorization 
      Authorize = false; 

      string[] roles = null; 
      //get roles for currently login user 
      if (HttpContext.Current.Session["Roles"] != null) 
      { 
       roles = (string[])HttpContext.Current.Session["Roles"]; 
      } 

      if (roles != null) 
      { 
       //for multiple roles 
       string[] keys = new string[roles.Length]; 
       int index = 0; 
       // for each role, there is separate key 
       foreach (string role in roles) 
       { 
        keys[index] = role + "-" + BusinessComponent + "-" + Action; 
        index++; 
       } 

       //access Authorization Details and compare with keys 
       if (HttpContext.Current.Application["AuthorizationDetails"] != null) 
       { 
        Hashtable authorizationDetails = (Hashtable)HttpContext.Current.Application["AuthorizationDetails"]; 

        bool hasKey = false; 
        foreach (var item in keys) 
        { 
         hasKey = authorizationDetails.ContainsKey(item); 
         if (hasKey) 
         { 
          Authorize = hasKey; 
          break; 
         } 
        } 

       } 
      } 
      return base.AuthorizeCore(httpContext); 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
    } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     try 
     { 
      filterContext.Controller.ViewData["ResturnJsonResponse"] = ResturnJsonResponse; 
      base.OnAuthorization(filterContext); 
      if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
      { 
       // auth failed, redirect to login page 
       filterContext.Result = new HttpUnauthorizedResult(); 

       return; 
      } 

      if (!Authorize) 
      { 
       //Authorization failed, redirect to Access Denied Page 
       filterContext.Result = new RedirectToRouteResult(
        new RouteValueDictionary{{ "controller", "Base" }, 
              { "action", "AccessDenied" } 
              //{ "returnUrl", filterContext.HttpContext.Request.RawUrl } 
              }); 
      } 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
    } 
} 
1

또한 당신의 행동에서 같이보기를 반환 할 수 있습니다

public ActionResult Index() 
       { 
        return View(@"~/Views/SomeView.aspx"); 
       } 
0

이것은 내가하고 결국 및 재사용 속성에 싸서 좋은 점은 그것을 무엇이다 : 아래로 내 구현은 요구 사항에 따라 리디렉션 (또는 당신이 원하는 결과대로 적용) 동안 원래 URL을 유지 :

public class AuthoriseSiteAccessAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 

     // Perform your condition, or straight result assignment here. 
     // For me I had to test the existance of a cookie. 
     if (yourConditionHere) 
      filterContext.Result = new SiteAccessDeniedResult(); 
    } 

} 

public class SiteAccessDeniedResult : ViewResult 
{ 
    public SiteAccessDeniedResult() 
    { 
     ViewName = "~/Views/SiteAccess/Login.cshtml"; 
    } 
} 

그런 다음 당신의 컨트롤러 당신에게 위스콘신에 속성 [SiteAccessAuthorise] 추가 sh에 대한 액세스 권한을 적용하거나 BaseController에 추가하십시오. 하지만 기본 컨트롤러로 리디렉션되는 작업에는 속성이 없어도 무한 루프에 걸릴 수 있습니다!

관련 문제