If I create an controller method that returns ActionResult, then call View() at the end, is there any way to have a Filter (or something simular) change the returned result from the ViewResult emitted by View() to a PartialViewResult based on conditions in the Request?
Clearly I can have code in the controller method itself that returns the ViewResult or PartialViewResult, but this comes up in a number of places so it seems like a good use of a Filter. I tried doing this in both methods of the IResultFilter and saw no change in the output.
If this is not possible then I will look at creating some methods in my base controller called something like ViewOrPartial that I can call instead of View, but I wanted to seek broader wisdom before giving up on the Filter (or something like it) approach.
Thanks, Matthew
Update: So it appears that at least one difference between what I had tried and what is now working based on Darin's code is that I had overridden OnResultExecuting (and I had also tried OnResultExecuted) and Darin's code overrides OnActionExecuted. Does that seem odd or am I perhaps overlooking something else? I am delighted to have it working but it seemed to make more sense that to attach it to the IResultFilter interface. I will have to look into the intention of the two interfaces more.
Yes, it is possible:
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var result = filterContext.Result;
var viewResult = result as ViewResult;
var someValue = filterContext.Controller.ValueProvider.GetValue("someValue");
if (viewResult != null && someValue != null && someValue.AttemptedValue == "foo")
{
// if the controller action returned a view result
// and the someValue parameter equals foo we replace the
// view result initially returned by the action by a
// partial view result
var partialResult = new PartialViewResult();
partialResult.ViewData.Model = viewResult.Model;
filterContext.Result = partialResult;
}
}
}
Then decorate:
[MyActionFilter]
public ActionResult Foo()
{
MyViewModel vm = ...
return View(vm);
}