2012-01-09 9 views
15

Estoy trabajando con nopCommerce y tengo que agregar mi único filtro de acción; sin embargo, no quiero modificar los controladores centrales para evitar que se sobrescriba mi código cuando una nueva actualización es lanzada.ASP.NET MVC: filtro de acción de registro sin modificar el controlador

he fijado mi Acción de filtrado:

public class ProductActionFilterAttribute : ActionFilterAttribute 
{ 

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

} 

Si tuviera que modificar el controlador, tan sólo pudiera añadir [ProductActionFilter] a la acción lo quiero asignado.

¿Hay alguna manera de registrar mi Action Filter personalizado en una acción específica sin modificar el controlador?

Respuesta

22

Creo que los filtros globales son lo que necesita.

Una vez que ha creado el filtro de registrarla en el Global.asax:

protected void Application_Start() { 

    AreaRegistration.RegisterAllAreas(); 

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

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

añadir lógica de validación personalizado para filtrar si desea aplicar no a todas las acciones.

+0

Gracias por su respuesta. Un filtro global se ve como una opción adecuada y, como dices, podría buscar un controlador/acción específico. Simplemente lanzando algo allí afuera, en lugar de usar 'GlobalFilters.Filters.Add', ¿el' FilterProviders.Providers.Add' funcionaría de la misma manera? No estoy 100% seguro de cómo funciona, pero lo he leído que le permite especificar un determinado controlador/acción ... –

+0

@Scrooby Sí, FilterProvider también puede funcionar. Por favor, consulte http://stackoverflow.com/questions/5312624/filters-add-vs-filterproviders-providers-add. – sashaeve

2

Si desea que su filtro se registre para cada acción (o de lo contrario está bien hacerlo), entonces MVC 3 le permite aplicar Global action filters. Por supuesto, esto requiere que nopCommerce esté basado en MVC 3, que creo que es la versión más nueva.

0

¿Qué tal crear una clase parcial. A partir de la versión 2.60 todos los controladores son parciales:

public partial class CatalogController : BaseNopController 

Usted puede poner el filtro a la clase y luego consultar el nombre de acción.

1

En NopCommerce 3.5 (la última a esta respuesta, y más reciente que la fecha de la pregunta), la mejor manera que he encontrado para agregar un filtro de acción global es creando un complemento con una implementación IStartupTask. Este método evita por completo la alteración de cualquier archivo core de NopCommerce.

El evento NopCommerce Application_Start inicializa el EngineContext, que crea la instancia NopEngine. La inicialización NopEngine encuentra todas las implementaciones IStartupTask y las ejecuta en el orden especificado. Entonces, un IStartupTask es el lugar para hacer cualquier cosa que deba suceder al inicio de la aplicación.

código de ejemplo siguiente:

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; } 
    } 
} 
Cuestiones relacionadas