3

Is it possible to access ActionArguments in an IExceptionFilter?

enter image description here

According to the above picutre Exception Filters run after Action Filters which have access to them. So I don't see why they can't.

In an ActionFilter you access it like this

public class MyFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        context.ActionArguments // I need access to this in order to find out what type the input argument(s) was.
    }
}

But an IExceptionFilter uses public void OnException(ExceptionContext context) instead.

Snæbjørn
  • 10,322
  • 14
  • 65
  • 124
  • What specifically are you trying to access ? – Shyju Nov 17 '17 at 15:22
  • I need to map PropertyNames in ValidationExceptions from FluentValidation to match the API model PropertyNames. So I need to know what input model was used. I basically need access to `context.ActionArguments.Values` – Snæbjørn Nov 17 '17 at 15:29
  • `ExceptionContext.ModelState` can give you the model state dictionary. Can you get what you are looking for from that ? – Shyju Nov 17 '17 at 15:41
  • `ModelState` is bascially a `IDictionary` I wouldn't be able to tell what the type of the action arguments were from that. Also `Modelstate` only has something in it if there were model binding problems. – Snæbjørn Nov 17 '17 at 15:46

2 Answers2

1

I figured it out :)

public class ExceptionFilter : IExceptionFilter, IActionFilter
{
    private IDictionary<string, object> _actionArguments;

    public void OnException(ExceptionContext context)
    {
        _actionArguments // great success!
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        _actionArguments = context.ActionArguments;
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // do nothing
    }
}
Snæbjørn
  • 10,322
  • 14
  • 65
  • 124
  • does mvc create a filter object for each request? if not isn't this going to collide for so many requests in a multithreaded environment ? – Hassan Khallouf Aug 26 '18 at 05:03
  • 1
    look at this answer, looks like this is not a proper way to do it https://stackoverflow.com/questions/8937200/are-actionfilterattributes-reused-across-threads-how-does-that-work – Hassan Khallouf Aug 26 '18 at 05:28
  • Unfortunately this does not work if the exception is thrown before OnActionExecuting is called. For example, it could be thrown by another filter exucted prior to this one. – Virus721 Oct 26 '22 at 14:43
0

This SO question shows you how to get access to the ActionDescriptor from the ControllerContext, the latter being available from the ExceptionContext.

Despite being unoptimized due to the use of reflection, I picked that solution over yours for my own needs, because your solution unfortunately does not work if the exception is thrown before OnActionExecuting is called, which can happen if it is thrown by another filter, but also because it relies on using states on action filters, which as mentionned by Hassan Khallouf in the comments is not guaranteed to work depending on the implementation.

Virus721
  • 8,061
  • 12
  • 67
  • 123