MVC3: возможно ли изменить тип результата вне кода самого действия? - PullRequest
3 голосов
/ 31 октября 2011

Если я создаю метод контроллера, который возвращает ActionResult, а затем вызываю View () в конце, есть ли способ, чтобы Filter (или что-то похожее) изменило возвращаемый результат из ViewResult, испускаемого View (), на PartialViewResult на основании условий в заявке?

Ясно, что у меня может быть код в самом методе контроллера, который возвращает ViewResult или PartialViewResult, но это встречается в ряде мест, так что это похоже на хорошее использование фильтра. Я попытался сделать это в обоих методах IResultFilter и не увидел изменений в выводе.

Если это невозможно, я посмотрю на создание некоторых методов в моем базовом контроллере, называемых чем-то вроде ViewOrPartial, которые я могу вызывать вместо View, но я хотел искать более мудрых решений, прежде чем отказаться от фильтра (или чего-то подобного ) подход.

Спасибо, Мэтью

Обновление. Похоже, что по крайней мере одно различие между тем, что я пробовал, и тем, что сейчас работает на основе кода Дарина, заключается в том, что я переопределил OnResultExecuting (и я также пробовал OnResultExecuted), а код Дарина переопределяет OnActionExecuted. Это кажется странным, или я, возможно, пропускаю что-то еще? Я рад, что он работает, но, кажется, имеет смысл подключить его к интерфейсу IResultFilter. Мне придется больше изучить намерения двух интерфейсов.

1 Ответ

9 голосов
/ 31 октября 2011

Да, это возможно:

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