2012-04-30 24 views
7

Tôi đang cố gắng xem qua bất kỳ thuộc tính xác thực nào có thể là trang trí các phương thức hành động trong bộ điều khiển của tôi trong ứng dụng MVC 3. Tôi đang làm điều này trong các phương thức mở rộng HtmlHelper của riêng tôi về cơ bản là trình bao bọc cho ActionLink (để cung cấp cho bạn bối cảnh của thông tin mà tôi có sẵn khi chạy). Tôi có một giải pháp cơ bản tại chỗ, nhưng các phương pháp quá tải vừa làm cho nó phát nổ. Tôi biết rằng khuôn khổ là nội bộ giải quyết các url để phương pháp hành động, nhưng sau khi xem xét thông qua mã cho System.Web.Mvc.LinkExtensions, tôi vẫn chưa tìm thấy chính xác như thế nào đó đang xảy ra, vì vậy tôi là một chút khó khăn như thế nào để giải quyết vấn đề này.Cách lấy các thuộc tính của Phương thức hành động được yêu cầu

Dưới đây là đoạn code tôi có cho đến nay để giải quyết phương pháp có liên quan:

private static bool _IsUserAuthorized(HtmlHelper html, 
    string controllerName, string actionName) 
{ 
    controllerName = controllerName ?? 
    html.ViewContext.RouteData.GetRequiredString("controller"); 

    var factory = ControllerBuilder.Current.GetControllerFactory(); 
    var controller = factory.CreateController(
    html.ViewContext.RequestContext, controllerName); 

    Type controllerType = controller.GetType(); 
    var methodInfo = controllerType.GetMethod(actionName, 
    BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 

    ... check authentication 
} 

Vì vậy, vấn đề hiện tại của tôi là khi một phương pháp được ghi đè, tôi nhận được "trận mơ hồ thấy" ngoại lệ. Tôi đoán tôi cần phải xử lý các RouteValues ​​để giải quyết bất kỳ tham số cho phương pháp để tôi có thể xác định một cách rõ ràng đúng. Có ai có một số gợi ý về cách làm điều này? Cách khác, khuôn khổ đã cung cấp một phương tiện để giải quyết các phương pháp chính xác cần thiết?

Cảm ơn bạn rất nhiều!

+0

OK, vì vậy tôi đã tiếp tục đào sâu trong mã nguồn MVC3 và có vẻ như tôi cần phải nhận được một trường hợp ControllerDescriptor và sử dụng để có ActionDescriptor cho phương thức hành động thích hợp. Vì vậy, nếu đó là trường hợp, làm thế nào để tôi có được ControllerContext của bộ điều khiển thích hợp khi phương thức hành động được yêu cầu không phải là bộ điều khiển trong HtmlHelper.ViewContext.Controller? –

+0

Bắt một ControllerContext hóa ra khá đơn giản. Bắt một ControllerDescriptor, không quá nhiều. Có suy nghĩ gì không? –

+0

Tìm thấy mã [ở đây] (http://weblogs.asp.net/jeffreyzhao/archive/2009/01/30/extend-asp-net-mvc-for-asynchronous-action.aspx) để nhận ControllerDescriptor và ActionDescriptor. Đến gần hơn ... –

Trả lời

2

EDIT: Đã cập nhật phương pháp để bao gồm thông tin chi tiết từ this page. Phiên bản cuối cùng này xem xét AuthorizationFilters cho phương thức hành động được yêu cầu và kiểm tra xem người dùng có được phép thực hiện hành động hay không.

Vì vậy, tôi tìm hiểu về System.Web.Mvc.ControllerActionInvoker và tìm ra phương pháp và phương thức xây dựng mà tôi cần. ControllerDescriptor.FindAction() kết thúc là khóa. Dưới đây, tôi đã sao chép các phương pháp tôi đã viết rằng sẽ lấy tất cả các thuộc tính

private static bool _IsUserAuthorized(HtmlHelper htmlHelper, 
    string controllerName, string actionName) 
{ 
    ControllerContext controllerContext = null; 
    //if controllerName is null or empty, we'll use the 
    // current controller in HtmlHelper.ViewContext. 
    if (string.IsNullOrEmpty(controllerName)) 
    { 
    controllerContext = htmlHelper.ViewContext.Controller.ControllerContext; 
    } 
    else //use the controller factory to get the requested controller 
    { 
    var factory = ControllerBuilder.Current.GetControllerFactory(); 
    ControllerBase controller = (ControllerBase)factory.CreateController(
     htmlHelper.ViewContext.RequestContext, controllerName); 
    controllerContext = new ControllerContext(
     htmlHelper.ViewContext.RequestContext, controller); 
    } 

    Type controllerType = controllerContext.Controller.GetType(); 
    ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType); 
    ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); 
    if (actionDescriptor == null) 
    return false; 

    FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(
    controllerContext, actionDescriptor)); 

    AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor); 
    foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters) 
    { 
    authFilter.OnAuthorization(authContext); 
    if (authContext.Result != null) 
     return false; 
    } 
    return true; 
} 
0

Cách thông thường để thêm mã ủy quyền là sử dụng Authorization Filter.

IAuthorizationFilter.OnAuthorization cung cấp đối tượng AuthorizationContext có thuộc tính ActionDescriptor.

+0

Chúng tôi đang sử dụng Bộ lọc ủy quyền, nhưng trừ khi tôi bỏ lỡ nó, khung không cung cấp cho bạn phương tiện kiểm tra ủy quyền đó trước khi gọi một hành động. Tôi đang cố gắng ẩn các liên kết từ những người dùng không có quyền truy cập để thực hiện các hành động được liên kết, vì vậy tôi cần kiểm tra các thuộc tính ủy quyền trước khi hiển thị html. Xử lý OnAuthorization sẽ là quá muộn trong chuỗi cho các chức năng tôi cần. –

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