Фон:
Мы поставляем html-файлы - «обертки» - от нашего клиента, в которые нам нужно внедрить производимый нами контент. У них разные оболочки для разных страниц, и мы должны вставить соответствующий контент в специальный тег, который они предоставляют в оболочке.
Имя файла оболочки соответствует имени метода действия. Таким образом, для приведенного ниже примера выполняется фильтр настраиваемых действий, который определит имя оболочки и затем вызовет метод в BaseController (который реализует каждый контроллер), который загрузит оболочку и вставит в нее наш контент.
[WrapperAction]
public ActionResult Home()
{
return View();
}
Причина, по которой я поместил это в ActionFilter, заключается в том, что я не хотел вызывать метод BaseController
, чтобы заполнить оболочку в каждом методе действия, который нуждался в оболочке. Я подумал, что гораздо уместнее украсить метод с помощью ActionFilterAttribute
WrapperAction
определяется следующим образом:
public class WrapperAction : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext aec)
{
var baseController = (BaseController)filterContext.Controller;
string wrapper = aec.RequestContext.RouteData.Values["action"].ToString();
baseController.PopulateWrapper(wrapper);
}
}
и PopulateWrapper
определяется как
public void PopulateWrapper(string wrapperName)
{
// get wrapper file from disk
Wrapper wrapper = _wrapperService.GetWrapper(Site.Id, wrapperName);
// populate the file with our CSS (it already has its own pre-populated CSS)
// our CSS file is determined by the id of a Site object.
AppHelper.PopulateWrapperCss(wrapper, this.Site.Id);
// make wrapper sections available to the Master page,
// split so that we can place our content around them
ViewData["WrapperTop"] = wrapper.WrapperTop;
ViewData["WrapperMiddle"] = wrapper.WrapperMiddle;
ViewData["WrapperBottom"] = wrapper.WrapperBottom;
}
Дилемма:
Однако теперь появилось новое требование. В оболочке есть несколько новых тегов, которые мне нужно заполнить, и мне нужно заполнить их различными данными в зависимости от метода действия, который вызывает оболочку. Эти данные определяются в методах действия, но эти данные необходимо использовать в методе PopulateWrapper, который вызывается WrapperAction
.
Теперь мне нужен метод, аналогичный
AppHelper.PopulateWrapperTags(wrapper, this.TagData);
и мне нужно, чтобы свойство TagData BaseController заполнялось данными. Я могу присвоить свойство в методе действия следующим образом
[WrapperAction]
public ActionResult Home()
{
base.TagData = GetTagData();
return View();
}
но такой вид поражает тот факт, что в первую очередь я имею в виду действие WrapperAction, потому что я не хочу, чтобы я так обращался к BaseController.
Вопрос:
Есть ли способ предоставить WrapperAction данные, необходимые для заполнения оболочки? Нужно ли принять удар и начать звонить
var tagData = GetTagData();
string wrapperName = RouteData.Values["action"].ToString();
base.PopulateWrapper(wrapperName, tagData);
в каждом контроллере? Есть ли лучший способ для меня это сделать?