roryf
roryf

Reputation: 30160

Detecting redirect in IActionFilter.OnActionExecuted reliably

I have an IActionFilter that does something in OnActionExecuted, however I don't want to perform this action when the controller result performs a redirect.

My initial thought was to check the type of the ActionResult as either RedirectResult or RedirectToRouteResult, but this isn't reliable as any type of result can perform a redirect (indeed I have two custom ones that do).

Is there another way I can detect when this happens or is it impossible since you won't know about the redirect until the action executes (which is too late to do what I want)?

Perhaps just checking for ViewResult and PartialViewResult would be more reliable.

Upvotes: 4

Views: 1780

Answers (2)

Dmytrii Nagirniak
Dmytrii Nagirniak

Reputation: 24088

... this isn't reliable as any type of result can perform a redirect (indeed I have two custom ones that do)

If they perform redirect it must be done by setting Result to the RedirectResult or similar, not just Response.Redirect.
If it is Response.Redirect, then it is plain wrong.
The example is AuthorizeAttribute which changes the Result to HttpUnauthorizedResult.

So you will still end up with the ControllerContext.Result and can operate on it.


Additionally, what about applying a convention: if the name of ActionResult type contains "Redirect" word than it is a redirect.

var isRedirect = filterContext.ActionResult.GetType().Name.Contains("Redirect");

If it looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.

The solution is not perfect of course, but simple and easily understandable.

Upvotes: 3

queen3
queen3

Reputation: 15511

I'd suggest just checking for the Result type. You can mark your custom actions with "[IsRedirect]", name them "...Redirect" or derive from "IRedirectResult" to detect.

Alternative solutions that come to my mind:

  1. Handle OnResultExecuted instead and check what Result has done to the HTTP context (URL changed, etc) - not sure if this works
  2. Manually call Result.Execute() with fake context and check what result has done to that fake context. You can have your fake context remember if any "Redirect" was called.

But just checking Result type is soo much simpler.

Upvotes: 0

Related Questions