我正在创建可以由用户设置的自定义颜色的网站(仅在某些页面上).我想在ActionFilterAttribute中获取该数据并将其设置在ViewBag中,以便我可以在_Layout.cshtml中获取数据.
这是我的ActionFilterAttribute ……
public class PopulateColorOptionsAttribute : ActionFilterAttribute { private readonly OptionsDataHelper optionsDataHelper; public PopulateOptionsAttribute(OptionsDataHelper optionsDataHelper) { this.optionsDataHelper = optionsDataHelper; } public override async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next) { await base.OnActionExecutionAsync(context,next); // Get the cemetery data and set it on the view bag. var personId = Convert.ToInt32(context.RouteData.Values["personId"]); context.Controller.ViewBag.OptionsData = await optionsDataHelper.GetValueAsync(personId,CancellationToken.None); } }
不幸的是,我在ViewBag上收到一条错误,指出:
‘object’ does not contain a definition for ‘ViewBag’ and no extension method ‘ViewBag’ accepting a first argument of type ‘object’ could be found (are you missing a using directive or an assembly reference?) [dnx451]
我很确定我对滤波器没有正确理解,我很欣赏如何实现我想要的指导.
解决方法
ActionExecutingContext.Controller声明为Object类型,因为框架不对哪些类可以作为控制器施加任何限制.
如果您始终创建从基本Controller类继承的控制器,那么您可以在过滤器中使用该假设并将context.Controller用作Controller:
public override async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next) { await base.OnActionExecutionAsync(context,next); var controller = context.Controller as Controller; if (controller == null) return; controller.ViewBag.Message = "Foo message"; }
如果你不能做出这个假设,那么你可以使用类似的方法检查上下文中的结果:
public override async Task OnResultExecutionAsync(ResultExecutingContext context,ResultExecutionDelegate next) { var viewResult = context.Result as ViewResult; //Check also for PartialViewResult and ViewComponentResult if (viewResult == null) return; dynamic viewBag = new DynamicViewData(() => viewResult.ViewData); viewBag.Message = "Foo message"; await base.OnResultExecutionAsync(context,next); }