2009-05-19 23 views
6

Tôi có một số BaseController mà tôi đưa vào một số dữ liệu trong bộ sưu tập ViewData bằng cách ghi đè OnActionExecuting.Calling FilterActribute OnActionExecuting trước khi OnActionExecuting của BaseController

Bây giờ tôi có một hành động trong một ChildController mà không cần dữ liệu xem đó.

Vì mục đích đó, tôi đã tạo một DontPopulateViewData ActionFilterAttribute đặt một bool trên BaseController ngăn không cho BaseController từ điền dữ liệu chế độ xem.

Sự cố: Phương thức ActionFilters OnActionExecuting được gọi sau số BaseController và không phải trước đây.

ActionFilters sẽ luôn được gọi trước khi ghi đè OnActionExecuting trong bộ điều khiển cơ sở và có cách nào để giải quyết vấn đề này không?

Trả lời

15

Ngoài những gì Marwan Aouida đăng và đề xuất (sử dụng ActionFilter trên lớp cơ sở), tôi không nghĩ rằng bạn sẽ có thể tạo một ActionFilter thực hiện trước khi quá tải OnActionExecuting() trên cơ sở lớp học. Các mã sau đây:

[MyActionFilter(Name = "Base", Order = 2)] 
public class MyBaseController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     Response.Write("MyBaseController::OnActionExecuting()<br>"); 
     base.OnActionExecuting(filterContext); 
    } 

    protected override void Execute(System.Web.Routing.RequestContext requestContext) 
    { 
     requestContext.HttpContext.Response.Write("MyBaseController::Execute()<br>"); 
     base.Execute(requestContext); 
    } 

    protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     Response.Write("MyBaseController::OnActionExecuted()<br>"); 
     base.OnActionExecuted(filterContext); 
    } 
} 

public class MyActionFilter : ActionFilterAttribute 
{ 
    public string Name; 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     filterContext.HttpContext.Response.Write("MyActionFilter_" + Name + "::OnActionExecuted()<br>"); 
     base.OnActionExecuted(filterContext); 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     filterContext.HttpContext.Response.Write("MyActionFilter_" + Name + "::OnActionExecuting()<br>"); 
     base.OnActionExecuting(filterContext); 
    } 
} 

public class MyTestController : MyBaseController 
{ 
    [MyActionFilter(Name = "Derived", Order = 1)] 
    public void Index() 
    { 
     Response.Write("MyTestController::Index()<br>"); 
    } 
} 

sản xuất sản lượng này:

MyBaseController::Execute() 
MyBaseController::OnActionExecuting() 
MyActionFilter_Derived::OnActionExecuting() 
MyActionFilter_Base::OnActionExecuting() 
MyTestController::Index() 
MyActionFilter_Base::OnActionExecuted() 
MyActionFilter_Derived::OnActionExecuted() 
MyBaseController::OnActionExecuted() 
+0

Cảm ơn. Và có, đặt logic vào một ActionFilter trên baseclass sẽ giải quyết vấn đề và thậm chí dẫn đến một thiết kế sạch hơn. –

0

Lớp ActionFilterAttribute có thuộc tính được gọi là "Thứ tự" mà bạn có thể sử dụng để đặt thứ tự các Bộ lọc hành động được thực hiện.
Trong trường hợp của bạn, bạn phải thiết lập thứ tự của các thuộc tính Filter trong BaseController đến 2 và các thuộc tính Filter trong DerivedController đến 1:

[MyFilter(Order=2)] 
public class BaseController:Controller 
{ 

    public ActionResult MyAction() { 

    } 

} 

[MySecondFilter(Order=1)] 
public class DerivedController:BaseController 
{ 

    public ActionResult AnotherAction() { 

    } 

} 

đọc này để biết thêm infos: http://msdn.microsoft.com/en-us/library/dd381609.aspx

Lưu ý: Tôi đã không kiểm tra điều này.

Các vấn đề liên quan