MVC3:是否可以在动作本身的代码之外更改结果类型?

时间:2011-10-30 20:07:11

标签: asp.net-mvc-3 custom-attributes action-filter

如果我创建一个返回ActionResult的控制器方法,然后在最后调用View(),有没有办法让Filter(或类似的东西)将View()发出的ViewResult的返回结果更改为PartialViewResult根据请求中的条件?

显然,我可以在控制器方法本身中使用返回ViewResult或PartialViewResult的代码,但这会出现在很多地方,所以它似乎很好地使用了Filter。我尝试在IResultFilter的两个方法中都这样做,并且没有看到输出的变化。

如果这不可能,那么我将在我的基本控制器中创建一些方法,称为ViewOrPartial,我可以调用而不是View,但我想在放弃Filter之前寻求更广泛的智慧(或类似的东西)方法。

谢谢, 马修

更新:所以看来我尝试过的和基于Darin代码的工作之间的至少一个区别是我覆盖了OnResultExecuting(我还尝试过OnResultExecuted),Darin的代码覆盖了OnActionExecuted。这看起来很奇怪还是我可能忽略了别的东西?我很高兴让它工作,但将它附加到IResultFilter接口似乎更有意义。我将不得不更多地研究这两个接口的意图。

1 个答案:

答案 0 :(得分:9)

是的,有可能:

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;
        }
    }
}

然后装饰:

[MyActionFilter]
public ActionResult Foo()
{
    MyViewModel vm = ...
    return View(vm);
}