2012-01-09 41 views
15

我正在使用nopCommerce,但我需要在我唯一的Action Filter中添加,但是,我不想修改核心控制器以避免我的代碼被覆蓋一個新的更新被髮布。ASP.NET MVC:在不修改控制器的情況下注冊動作篩選器

我設置我的行爲過濾器:

public class ProductActionFilterAttribute : ActionFilterAttribute 
{ 

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

} 

如果我修改控制器,我可以只添加[ProductActionFilter]我想要它分配給動作。

有沒有一種方法可以在不修改控制器的情況下將自定義動作過濾器註冊到特定動作?

回答

22

我認爲全球過濾器是你需要的。

一旦你創建的過濾器在Global.asax註冊它:

protected void Application_Start() { 

    AreaRegistration.RegisterAllAreas(); 

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

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

添加自定義驗證邏輯來​​過濾,如果你想不適用它的所有操作。

+0

感謝您的答覆。全局過濾器看起來像是一個合適的選項,正如您所說,我可以檢查特定的控制器/操作。只是拋出一些東西,而不是使用'GlobalFilters.Filters.Add','FilterProviders.Providers.Add'的工作原理是什麼?我不是100%確定它是如何工作的,但我讀過它可以讓你指定一個特定的控制器/操作... – 2012-01-09 10:25:01

+0

@Scrooby是的,FilterProvider也可以工作。請檢查http://stackoverflow.com/questions/5312624/filters-add-vs-filterproviders-providers-add。 – sashaeve 2012-01-09 10:43:55

2

如果您希望爲每個操作註冊您的過濾器(否則可以這樣做),那麼MVC 3允許您應用Global action filters。當然這需要nopCommerce建立在MVC 3上,我相信最新的版本是?

0

怎麼樣創建一個部分類。隨着2.60版本的所有控制器都諧音:

public partial class CatalogController : BaseNopController 

你可以把過濾器類,然後查詢動作的名稱。

1

在NopCommerce 3.5中(這個答案是最新的,比問題日期還要新),我發現添加全局動作過濾器的最佳方式是創建一個插件,其中包含IStartupTask實現。這種方法完全避免了改變任何NopCommerce核心文件。

NopCommerce Application_Start事件初始化EngineContext,創建NopEngine實例。 NopEngine初始化查找所有IStartupTask實現,並按其指定的順序執行它們。因此IStartupTask是在應用程序啓動時需要做的任何事情的地方。

示例代碼如下:

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; } 
    } 
} 
相關問題