【发布时间】:2010-09-09 16:54:44
【问题描述】:
背景:
我们从客户那里获得了 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;
}
困境:
然而,现在出现了一个新要求。我需要填充包装器中的一些新标签,并且我必须根据调用包装器的操作方法使用不同的数据填充它们。该数据在操作方法中确定,但数据需要在由WrapperAction 调用的 PopulateWrapper 方法中使用。
我现在需要一个类似于
的方法AppHelper.PopulateWrapperTags(wrapper, this.TagData);
而且我需要有一些方法让 BaseController 的 TagData 属性填充数据。我可以在 action 方法中分配属性,如下所示
[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);
在每个控制器中?我有更好的方法吗?
【问题讨论】:
标签: c# asp.net-mvc action-filter