2012-01-09 30 views
15

Tôi đang làm việc với nopCommerce và tôi cần thêm Bộ lọc hành động duy nhất của mình, tuy nhiên, tôi không muốn sửa đổi bộ điều khiển lõi để tránh mã của mình bị ghi đè khi một bản cập nhật mới được phát hành.ASP.NET MVC: Đăng ký bộ lọc hành động mà không sửa đổi bộ điều khiển

tôi đã thiết lập Filter Action tôi:

public class ProductActionFilterAttribute : ActionFilterAttribute 
{ 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult) 
     { 
      ... 
     } 
     base.OnActionExecuted(filterContext); 
    } 

} 

Nếu tôi được sửa đổi bộ điều khiển, tôi chỉ có thể thêm [ProductActionFilter] với hành động Tôi muốn nó được gán cho.

Có cách nào tôi có thể đăng ký Bộ lọc hành động tùy chỉnh của mình cho một hành động cụ thể mà không sửa đổi bộ điều khiển không?

Trả lời

22

Tôi nghĩ rằng bộ lọc toàn cầu là những gì bạn cần.

Khi bạn tạo ra các bộ lọc đăng ký nó trong global.asax:

protected void Application_Start() { 

    AreaRegistration.RegisterAllAreas(); 

    // Register global filter 
    GlobalFilters.Filters.Add(new MyActionFilterAttribute()); 

    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 
} 

Thêm logic xác nhận tùy chỉnh để lọc nếu bạn muốn áp dụng nó không phải cho tất cả các hành động.

+0

Cảm ơn phản hồi của bạn. Một bộ lọc toàn cục trông giống như một tùy chọn phù hợp và như bạn nói, tôi có thể kiểm tra một bộ điều khiển/hành động cụ thể. Chỉ cần ném một cái gì đó ra khỏi đó, thay vì sử dụng 'GlobalFilters.Filters.Add', sẽ' FilterProviders.Providers.Add' làm việc giống nhau không? Tôi không chắc chắn 100% cách thức hoạt động, nhưng tôi đã đọc nó cho phép bạn chỉ định một bộ điều khiển/hành động nhất định ... –

+0

@Scrooby Vâng, FilterProvider cũng có thể hoạt động. Vui lòng kiểm tra http://stackoverflow.com/questions/5312624/filters-add-vs-filterproviders-providers-add. – sashaeve

2

Nếu bạn muốn bộ lọc của mình được đăng ký cho mọi hành động (hoặc nếu không thì OK), thì MVC 3 cho phép bạn áp dụng Global action filters. Tất nhiên điều này đòi hỏi rằng nopCommerce được xây dựng trên MVC 3, mà tôi tin rằng phiên bản mới nhất là?

0

Điều gì về việc tạo một lớp học một phần. Kể từ phiên bản 2.60 tất cả các trình điều khiển đều là partials:

public partial class CatalogController : BaseNopController 

Bạn có thể đặt bộ lọc cho lớp và sau đó truy vấn tên hành động.

1

Trong NopCommerce 3.5 (mới nhất là câu trả lời này và mới hơn ngày câu hỏi), cách tốt nhất tôi đã tìm thấy để thêm bộ lọc hành động chung là tạo một plugin có triển khai IStartupTask trong đó. Phương pháp này hoàn toàn tránh thay đổi bất kỳ tệp lõi NopCommerce nào.

Sự kiện NopCommerce Application_Start khởi tạo EngineContext, tạo phiên bản NopEngine. Khởi tạo NopEngine tìm tất cả việc triển khai IStartupTask và thực hiện chúng theo thứ tự được chỉ định của chúng. Vì vậy, một IStartupTask là nơi để làm bất cứ điều gì cần phải xảy ra khi bắt đầu ứng dụng.

Mẫu mã bên dưới:

public class Plugin : BasePlugin 
{ 
    public Plugin() 
    { 
    } 

    /// <summary> 
    /// Check to see if this plugin is installed 
    /// </summary> 
    public static bool IsInstalled(ITypeFinder typeFinder) 
    { 
     IEnumerable<Type> types = typeFinder.FindClassesOfType<IPluginFinder>(true); 

     if (types.Count() == 1) 
     { 
      IPluginFinder plugins = Activator.CreateInstance(types.First()) as IPluginFinder; 
      PluginDescriptor descriptor = plugins.GetPluginDescriptorBySystemName("MyPluginName"); 

      if (descriptor != null && descriptor.Installed) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

/// <summary> 
/// Redirects to the 404 page if criteria not met 
/// </summary> 
public class FluffyTextureRequiredAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (Kitten.Texture != Textures.Fluffy) 
     { 
      var routeValues = new RouteValueDictionary(); 
      routeValues.Add("controller", "Common"); 
      routeValues.Add("action", "PageNotFound"); 

      filterContext.Result = new RedirectToRouteResult(routeValues); 
     } 
    } 
} 

/// <summary> 
/// Does application start event stuff for the plugin, e.g. registering 
/// global action filters 
/// </summary> 
public class StartupTask : IStartupTask 
{ 
    private ITypeFinder _typeFinder; 

    public StartupTask() 
    { 
     //IStartupTask objects are created via Activator.CreateInstance with a parameterless constructor call, so dependencies must be manually resolved. 
     _typeFinder = EngineContext.Current.Resolve<ITypeFinder>(); 
    } 

    public void Execute() 
    { 
     // only execute if plugin is installed 
     if (Plugin.IsInstalled(_typeFinder)) 
     { 
      // GlobalFilters is in System.Web.Mvc 
      GlobalFilters.Filters.Add(new FluffyTextureRequiredAttribute()); 
     } 
    } 

    public int Order 
    { 
     get { return int.MaxValue; } 
    } 
} 
Các vấn đề liên quan