web-dev-qa-db-fra.com

Comment obtenir le modèle actuel dans le filtre d'action

J'ai un filtre d'action générique et je veux obtenir le modèle actuel dans la méthode OnActionExecuting. Ma mise en œuvre actuelle est comme ci-dessous:

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

Cela fonctionne bien si tous mes noms de modèles sont identiques. Mais je veux utiliser des noms de modèles différents. 

Comment résoudre ce problème?

Modifier  

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

ActionExecutingContext.ActionArguments est juste un dictionnaire,

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

Et vous devez le parcourir en boucle si vous devez éviter le nom de paramètre codé en dur ("modèle"). De même réponse SO pour asp.net:

Lorsque nous créons un filtre d'action générique devant travailler sur une classe d'objets similaires pour certaines exigences spécifiques, nos modèles peuvent implémenter une interface => savoir quel argument est le modèle sur lequel nous devons travailler et nous pouvons appeler les méthodes L'interface.

Dans votre cas, vous pouvez écrire quelque chose comme ceci:

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

Vous pouvez utiliser la propriété ActionExecutingContext.Controller

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

et convertir le résultat en contrôleur MVC de base obtenir l’accès au modèle:

((Controller)actionExecutingContext.Controller).ViewData.Model
5
Set

Si votre action de contrôleur comporte plusieurs arguments et que dans votre filtre, vous souhaitez sélectionner celui lié via [FromBody], vous pouvez utiliser la réflexion pour effectuer les opérations suivantes:

public void OnActionExecuting(ActionExecutingContext context)
{
    foreach (ControllerParameterDescriptor param in context.ActionDescriptor.Parameters) {
        if (param.ParameterInfo.CustomAttributes.Any(
            attr => attr.AttributeType == typeof(FromBodyAttribute))
        ) {             
            var entity = context.ActionArguments[param.Name];

            // do something with your entity...
0
B12Toaster