views:

216

answers:

2

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.

A: 

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.

queen3
My solution at the minute is to check is the result is of type ViewResultBase, which covers ViewResult and PartialViewResult. I can't yet think of any other result that I might want to cover, other than something I'd add myself.
roryf
A: 

... 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.

Dmytrii Nagirniak
AuthorizeAttribute executes before the controller is invoked, I have custom ActionResults that are being returned by my controller action. How can I change the result when ActionResult::ExecuteResult is called?
roryf