2016-08-11 9 views
7

Mam ogólny filtr działania i chcę uzyskać bieżący model w metodzie OnActionExecuting. Moja obecna implementacja wygląda następująco:Jak uzyskać bieżący model w filtrze działania

public class CommandFilter<T> : IActionFilter where T : class, new() 
{ 
     public void OnActionExecuting(ActionExecutingContext actionContext) 
     { 
      var model= (T)actionContext.ActionArguments["model"]; 
     } 
} 

Działa dobrze, jeśli moje wszystkie nazwy modeli są takie same. Ale chcę używać nazw modeli differnet.

Jak rozwiązać ten problem?

Edit

public class HomeController : Controller 
{ 
    [ServiceFilter(typeof(CommandActionFilter<CreateInput>))] 
    public IActionResult Create([FromBody]CreateInput model) 
    { 
     return new OkResult(); 
    } 
} 
+0

http://stackoverflow.com/questions/872796/asp-net-mvc-accessing-view-model-from-a-custom -action-filter – user2184057

+0

@ user2184057 jest to model widoku, a nie model żądania – Set

Odpowiedz

4

ActionExecutingContext.ActionArguments jest po prostu słownik,

/// <summary> 
    /// Gets the arguments to pass when invoking the action. Keys are parameter names. 
    /// </summary> 
    public virtual IDictionary<string, object> ActionArguments { get; } 

i jeśli chcesz uniknąć nazwy parametru na sztywno ("model"), musisz wykonać pętlę. Od the same SO answer dla ASP.NET:

Kiedy tworzymy rodzajowe filtr działania, który musi pracować na klasy podobnych obiektów dla niektórych specyficznych wymagań, możemy mieć nasze modele zaimplementować interfejs => wiedzieć, które argumentem jest model, nad którym musimy popracować i możemy wywołać metody za pomocą interfejsu.

W ty przypadku można napisać coś takiego

public void OnActionExecuting(ActionExecutingContext actionContext) 
{ 
    foreach(var argument in actionContext.ActionArguments.Values.Where(v => v is T))) 
    { 
     T model = argument as T; 
     // your logic 
    } 
} 
+0

"jest T", a następnie "jako T" jakiś sposób, aby poprawić ten kod? rzutujesz dwa razy z mojego punktu widzenia ... –

4

Można użyć ActionExecutingContext.Controller własność

/// <summary> 
    /// Gets the controller instance containing the action. 
    /// </summary> 
    public virtual object Controller { get; } 

i wynik konwersji do base MVC Controller uzyskać dostęp do modelu

((Controller)actionExecutingContext.Controller).ViewData.Model 
+0

zgłasza wyjątek dotyczący rzutowania: Nie można rzutować obiektu typu "MyNamespace.HomeController", aby wpisać "Microsoft.AspNetCore.Mvc.Controller". –

+0

czy mógłbyś pokazać definicję HomeController? – Set

+0

oo przepraszam, zapomniałem definicji bazy 'Controller'. Edytowałem kod, ale teraz model jest zerowy (być może brakuje mi czegokolwiek). zobacz moją aktualizację. –

Powiązane problemy