Search code examples
c#asp.net-coreasp.net-core-mvc

How to get current model in action filter


I have a generic action filter, and I want to get current model in the OnActionExecuting method. My current implementation is like below:

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

It works well if my all model names are same. But i want to use differnet model names.

How to solve this problem?

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

Solution

  • ActionExecutingContext.ActionArguments is just a dictionary,

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

    And you need to loop through it if you need to avoid hardcoded parameter name ("model"). From the same SO answer for asp.net:

    When we create a generic action filter that needs to work on a class of similar objects for some specific requirements, we could have our models implement an interface => know which argument is the model we need to work on and we can call the methods though the interface.

    In your case you may write something like this:

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