7

Tôi có một ứng dụng ASP.Net MVC 3 đơn giản có một số bộ điều khiển và một vài thao tác tốt.ASP.Net MVC 3: Inverse Authorize Attribute

Bây giờ, vì đây là một ứng dụng dựa trên người dùng, hầu hết các hành động của trình điều khiển yêu cầu người dùng phải được xác thực. MVC xử lý tốt với thuộc tính Authorize được tích hợp sẵn mà bạn có thể sử dụng để trang trí các bộ điều khiển và/hoặc các hành động riêng lẻ.

Điều tuyệt vời là bạn có thể áp dụng các thuộc tính để chỉ bộ điều khiển và tất cả các hành động cho rằng điều khiển nhất định sẽ có nó áp dụng quá - nhiều đánh máy lưu;)

Nhưng tôi có một bộ điều khiển với, cho phép nói, 10 hành động. Nhưng tôi muốn một trong những hành động không có thuộc tính Authorize được áp dụng.

Có, tôi có thể áp dụng thuộc tính này cho thuộc tính còn lại và loại bỏ nó khỏi bộ điều khiển sẽ thực hiện chính xác những gì tôi cần. Nhưng có cách nào để giữ cho nó được áp dụng cho bộ điều khiển và chỉ chọn loại trừ một trong các hành động?

có hiệu quả, muốn một cái gì đó giống như ...

[!Authorize] hoặc [NotAuthorize]

Tôi biết tôi có thể tạo ra một tùy chỉnh mà sẽ thực hiện công việc, nhưng những gì tôi muốn biết là nếu có một xây dựng -trong cách để làm điều này? hoặc tôi có phải áp dụng thuộc tính cho tất cả 9 hành động khác không?

Trả lời

2

Phil Haack đã viết một bài đăng blog gần đây đối phó với tình huống này chính xác:

Conditional Filters in ASP.NET MVC 3

Giải pháp của ông bao gồm viết một tùy chỉnh "nhà cung cấp bộ lọc có điều kiện" cho phép một để chỉ một điều kiện lọc các thuộc tính của một hành động phương pháp.

Chi tiết và lý do nằm trong bài đăng của anh ấy, nhưng mã tương đối đơn giản. Đầu tiên, tạo các nhà cung cấp bộ lọc:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 

public class ConditionalFilterProvider : IFilterProvider { 
    private readonly 
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions; 

    public ConditionalFilterProvider(
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions) 
    { 

     _conditions = conditions; 
    } 

    public IEnumerable<Filter> GetFilters(
     ControllerContext controllerContext, 
     ActionDescriptor actionDescriptor) { 
    return from condition in _conditions 
      select condition(controllerContext, actionDescriptor) into filter 
      where filter != null 
      select new Filter(filter, FilterScope.Global, null); 
    } 
} 

Và sau đó áp dụng nó:

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ? 
     new MyFilter() : null, 
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null 
}; 

var provider = new ConditionalFilterProvider(conditions); 
FilterProviders.Providers.Add(provider); 
10

Lưu ý rằng một thuộc tính mới đã được thêm vào trong ASP.NET MVC 4,0 thực hiện chính xác rằng:
[AllowAnonymous]