-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ActionFilter should not be called if HttpResponseMessage had been populated by previous ActionFilter #30
Comments
Having looked at this issue this morning, here are my findings. TLDR; I think that a change is needed, but the original example is not 100% applicable, and I think the PR could do with an adjustment. The reason that Filter2 in the 'normal' filter example is never called is because you return the response message directly, without invoking the continuation method to continue the chain. If you change your code in Filter1 to:
That will cause Filter2 to be invoked, but so will the Action method, effectively ignoring your forbidden, which is also definitely not what you want. It feels to me that IAutofacActionFilter isn't particularly analogous to IActionFilter, because IActionFilter is the low-level implementation that has to handle the continuations itself. The behaviour of IAutofacActionFilter is more of a match with the public methods on the actual ActionFilterAttribute class, which deals with all the continuation logic for you. If you change your original example to derive from ActionFilterAttribute then the code becomes much more similar to the Autofac example:
Now, in this updated example, the code still doesn't execute Filter2. The reason it doesn't is because of explicit code in the ActionFilterAttribute class: Since the ActionFilterWrapper is effectively just a nested collection of ActionFilterAttribute-style behaviour, I feel like it should emulate the same behaviour as the ActionFilter, so we should replicate the 'stop if response is set' behaviour. With regards to the provided PR, part of the change is valid; in the OnActionExecuting handler, I believe we should not continue the filter loop if the response is set by a filter. However, the change in the PR that applies the same behaviour to OnActionExecuted is not valid. The non-autofac ActionFilterAttribute behaviour is to execute all the filters for OnActionExecuted, and that makes sense. Only OnActionExecuting would typically be used to 'stop' a request. In addition, the provided PR continues to loop after the response has been created, whereas I would suggest breaking out of the loop to avoid the additional 'FilterMatchesMetadata' checks on subsequent filters. I'll get round to providing an updated fix (and tests) for this issue shortly. |
…nExecutedAsync if response has been set by a prior filter
Fix for issue #30 - Do not execute filters after a response has been set
Let's imagine we have a controller:
Now we want to decorate it with two action filters
Filter1
Filter2
Filters added to HttpConfiguration.Filters:
Now if we run an app and navigate to route, in Output Window will be shown only "Filter 1 invoked", Filter2 will not be fired.
################################################################################
If we make the same only using IAutofacActionFilter, both filters will be fired
Filter1
Filter2
Global.asax.cs
Run an app and navigate to route, in Output Window will be shown "Filter 1 invoked", "Filter 2 invoked". Property Response of actionContext parameter in OnActionExecutingAsync method of Filter2 equal to Forbidden response.
Libraries:
Autofac 4.6.2
Autofac.WebApi2 4.1.0
The text was updated successfully, but these errors were encountered: