2012-12-07 22 views
9

Sau khi thực hiện blog tuyệt vời này post bởi Simon Tôi đã biết rằng mô hình ràng buộc xảy ra sớm hơn so với thực hiện bộ lọc (ngay cả trước khi bộ lọc ủy quyền). Nếu yêu cầu không được ủy quyền thì nó sẽ bị từ chối càng sớm càng tốt và trong trường hợp đó, tôi thích chạy các bộ lọc ủy quyền trước quá trình ràng buộc mô hình. Ngoài ra, bằng cách này, chúng tôi có thể tiết kiệm thời gian tránh quét yêu cầu, tạo các trường hợp mô hình và thực hiện xác thực.Tại sao mô hình ràng buộc xảy ra sớm hơn so với các bộ lọc

Có lý do gì khiến tôi không hiểu tại sao đường ống xử lý yêu cầu MVC được thiết kế sao cho mô hình ràng buộc nên xảy ra trước bộ lọc?

Trả lời

7

Trong asp.net mvc3, bộ lọc ủy quyền thực thi trước mô hình ràng buộc, không phải sau (xem mã bên dưới).

Ràng buộc mô hình xảy ra trước các bộ lọc vì ActionExecutingContext (tham số của IActionFilter.OnActionExecuting) chứa các tham số của hành động. Có lẽ họ nên lười biếng tải những thông số đó.

Mã sau đây là từ System.Web.Mvc.ControllerActionInvoker.

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) 
{ 
    // code removed for brevity 
    try 
    { 
     // Notice the authorization filters are invoked before model binding 
     AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor); 
     if (authContext.Result != null) { 
      // the auth filter signaled that we should let it short-circuit the request 
      InvokeActionResult(controllerContext, authContext.Result); 
     } 
     else { 
      if (controllerContext.Controller.ValidateRequest) { 
       ValidateRequest(controllerContext); 
      } 
      // GetParameterValues does the model binding 
      IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor); 
      ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters); 
      InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result); 
     } 
    } 
    // code removed for brevity 
}