4

간단한 조치 필터를 사용하여 사용자가 로그인했는지 확인하고 사용자 ID를 검색합니다.ActionFilter에서 C# MVC의 Controller Action으로 변수를 전달하는 방법은 무엇입니까?

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     // Pass the ID through to the controller? 
     ..... 
    } 
} 

어떻게이 ID를 내 컨트롤러 동작에 전달할 수 있습니까?

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = .... 
    } 
} 

내가 할 수있는 ViewBag에 해당하는 항목이 있습니까? 아니면 필터와 컨트롤러 액션 사이에 변수와 객체를 전달할 수있는 다른 기술이 있습니까?

답변

5

당신처럼 대부분의 다른 표준 데이터를 얻기 위해 Id와 속성을 얻을 확장 방법이있는 Controller.User을 사용할 수 있습니다 이 같은 ViewData/ViewBag를 사용할 수 있습니다

1.) ViewData

주 :을을 ViewData의 경우 당신은 당신이 일반해야 하나 단계를 수행해야합니다 ViewBag

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 

     filterContext.Controller.ViewBag.Id = idValue; 
    } 
} 

사용 컨트롤러 기능

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = (int)ViewData["Id"]; 
    } 
} 

2)에

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 
     filterContext.Controller.ViewData.Add("Id", idValue); 
    } 
} 

그리고 그것을 ecast 그리고 컨트롤러

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = ViewBag.Id; 
    } 
} 
+0

감사합니다. ViewBag 대신에 @Luiso의 대답에 의해 제안 된 것처럼 TempData를 사용 했음에도 불구하고 ViewData를 사용하면 예제를 사용하여 실제로 사용하는 방법에 대한 최상의 정보를 얻을 수 있으며 기술은 ViewBag에서 TempData와 동일합니다. 나는 이것이 View를위한 것이 아닌 Temporary Data라는 것을 알기 때문에 TempData를 사용하는 것이 더 논리적이다. –

4

ActionExecutingContext에는 호출 컨트롤러에 대한 참조가 포함되어 있습니다. 이것을 Controller 클래스에서 파생 된 사용자 정의 컨트롤러 클래스와 혼합하여 사용하면 id을 컨트롤러의 인스턴스 변수로 저장할 수 있습니다.

사용자 정의 컨트롤러는

Public Class MyController : Controller 
{ 
    Public int Id {get;set;} 
} 

는 LoginFilter

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     ((MyController)filterContext.Controller).Id = id; 
     //Assign the Id by casting the controller (you might want to add a if ... is MyController before casting) 
    } 
} 

컨트롤러

[LoginFilter] 
public class Dashboard : MyController 
{ 
    public ActionResult Index() 
    { 
     //Read the Id here 
     int id = this.Id 
    } 
} 
+0

는 I이 용액의 논리처럼 , 그것은 직접 ID를 심는다는 점에서 컨트롤러에 들어가서 꽤 "깔끔하다."그러나 실제 구현은 나중에 코드를 유지하는 누구에게나 약간 불투명 한 것처럼 보이기 때문에 그걸로 가지 않기로 결정했습니다. ID는 설명없이 마술처럼 설정되어있는 것처럼 보입니다. –

+0

공정한 비평, 감사 –

6

당신은 수행하여 ViewBag를 사용할 수 있습니다

filterContext.Controller.ViewBag.Id = id; 

을 입력하면 을 입력하면 TempData과 같은 모든 입력란에 액세스 할 수 있습니다. 당신은 아마도 사용자의 ID를 얻기 위해 다음 OWIN를 사용하는 경우

는 그럼에도 불구하고, 당신은 Name

+0

흠, 이것은 깔끔한 해결책처럼 보입니다.논리적으로, ViewBag를 사용하는 것은 아마도 이해가되지 않을 것이지만, 아마도 TempData가 좋은 장소 일 것입니다. 나는 OWIN을 사용하지 않고있다. (최소한 우리가 인증 기술을 혼합하고 있기 때문에 프로젝트의이 부분은 아니다.) –

관련 문제