Концепция Interception Filter в AspNet Mvc

Существует паттерн, называемый InterceptionFilter. Коротко о его сути. Его задача, предоставить возможность фильтровать поток данных на входе в какой-то модуль и на выходе(Фильтры перехватчики, если дословно ) :).
После выхода бета версии Asp Net Mvc. Было внесено предложение о реализации этого паттерна и было даже предложено решение. И по многочисленным просьбам телезрителей команда разработчиков, занимающаяся разработкой AspNetMvc, включила в CTP, решение этого паттерна.
Ура сказали мы и многие разработчики. Салют мальчишам-кибальчишам из майкрософта.
Это при сказка, а теперь будет сказка.

И вот решили мы написать свой фильтр. Задача которого состояла в добавлении кое каких данных во ViewData и передача его во View. Радостно размахивая клавами мы быстренько написали этот фильтр который состоял из одного метода.

public override void OnActionExecuted(FilterExecutedContext filterContext)
{
IFilterViewData filterData = ((filterContext.Controller as Controller).ViewData['Filter'] as IFilterViewData);
filterData.IsActive = true;
}

Теперь не меннее радостно ждем эти данные во View. Ага, как же, дождались!
Не знаю о чем думали ТАМ. Но метод OnActionExecuted действительно исполняется после отработки метода-экшена.
Он исполняется даже после обработки View(RenderView).
Какой же это FilterController подумали мы и пошли курить бамбук. Это какой-то FilterMethod, а его мы вовсе на ждали.

Погуглив совсем немного наткнулись на предложение в форуме aspnet. Где просят сделать что-то вроде OnRenderView.

public ProductViewData : IEntityContainer
{
object IEntityContainer.Entity { get { return this.Product; } }

public Product Product { get; set; }
public List<string> OtherProperty { get; set; }
// etc.
}


public class MyFilterAttribute : ActionFilterAttribute
{
private string[] acceptedFormats = new string[]{"json", "xml"};

public override object OnRenderView(ViewContext viewContext)
{
string format = viewContext.HttpContext.Request["format"];

if( string.IsNullrEmpty( format ) )
return;

if( !acceptedFormats.Contains( format.ToLower() ) )
return;

if( viewContext.ViewData is IEntityContainer)
viewContext.ViewData = (viewContext.ViewData as IEntityContainer).Entity;
}
}

Задача осталось решения от разработчика нету.
Единственным выходом на данные момент это использовать стандартную ViewData, аля словарь.
Вносить изменения в OnExecutingAction и молится что в контроллере никто не перезаписал его и не использовал типизированную ViewData

Комментариев нет: