2012-01-09 18 views
15

Pracuję z nopCommerce i muszę dodać tylko mój filtr akcji, jednak nie chcę modyfikować podstawowych kontrolerów, aby mój kod nie został nadpisany nowa aktualizacja została wydana.ASP.NET MVC: Zarejestruj filtr akcji bez modyfikowania kontrolera

mam ustawić mojego działania filtra:

public class ProductActionFilterAttribute : ActionFilterAttribute 
{ 

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

} 

Gdybym modyfikować kontroler, mogę tylko dodać [ProductActionFilter] działaniu chcę przypisany.

Czy istnieje sposób, w jaki mogę zarejestrować mój niestandardowy filtr akcji do określonej akcji bez modyfikowania kontrolera?

Odpowiedz

22

Myślę, że filtry globalne są tym, czego potrzebujesz.

Po utworzeniu filtru zarejestrować go w global.asax:

protected void Application_Start() { 

    AreaRegistration.RegisterAllAreas(); 

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

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

Dodaj logiki zwyczaj sprawdzania filtrować jeśli chcesz zastosować je nie do wszystkich działań.

+0

Dzięki za odpowiedź. Filtr globalny wygląda jak odpowiednia opcja i, jak mówisz, mogę sprawdzić konkretny kontroler/akcję. Wystarczy rzucić coś tam, zamiast używać "GlobalFilters.Filters.Add", czy "FilterProviders.Providers.Add" działa tak samo? Nie jestem w 100% pewny, jak to działa, ale przeczytałem, pozwala określić konkretny kontroler/akcję ... –

+0

@Scrooby Tak, FilterProvider może również działać. Sprawdź http://stackoverflow.com/questions/5312624/filters-add-vs-filterproviders-providers-add. – sashaeve

2

Jeśli chcesz, aby twój filtr był rejestrowany dla każdej akcji (lub w przeciwnym razie jest OK), wówczas MVC 3 pozwala na zastosowanie Global action filters. Oczywiście wymaga to, aby nopCommerce zostało zbudowane na MVC 3, która, jak sądzę, jest najnowszą wersją?

0

Co z tworzeniem klasy częściowej. Od wersji 2.60 wszystkie kontrolery są częściowe:

public partial class CatalogController : BaseNopController 

Możesz umieścić filtr w klasie, a następnie zapytać nazwę akcji.

1

W NopCommerce 3.5 (najnowsze od tej odpowiedzi i nowszej niż data pytania) najlepszym sposobem, jaki znalazłem, aby dodać globalny filtr akcji, jest utworzenie wtyczki z implementacją IStartupTask. Ta metoda całkowicie zapobiega zmianie jakichkolwiek podstawowych plików NopCommerce.

Zdarzenie NopCommerce inicjuje numer EngineContext, który tworzy instancję NopEngine. Inicjalizacja NopEngine znajduje wszystkie implementacje IStartupTask i wykonuje je w ich określonej kolejności. Tak więc IStartupTask jest miejscem do zrobienia wszystkiego, co musi się wydarzyć podczas uruchamiania aplikacji.

Przykładowy kod poniżej:

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; } 
    } 
} 
Powiązane problemy