Asp.net core 从ActionFilterAttribute设置ViewBag

Asp.net core 从ActionFilterAttribute设置ViewBag,asp.net-core,asp.net-core-mvc,Asp.net Core,Asp.net Core Mvc,我正在创建的站点自定义颜色可以由用户设置(仅在某些页面上)。我想在ActionFilterAttribute中获取数据,并将其设置在ViewBag中,这样我就可以在my_Layout.cshtml中获取数据 这是我的ActionFilterAttribute public class PopulateColorOptionsAttribute : ActionFilterAttribute { private readonly OptionsDataHelper optionsDataH

我正在创建的站点自定义颜色可以由用户设置(仅在某些页面上)。我想在ActionFilterAttribute中获取数据,并将其设置在ViewBag中,这样我就可以在my_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”不包含“ViewBag”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“ViewBag”(是否缺少using指令或程序集引用?[dnx451]


我很确定我没有正确地理解过滤器的某些方面,我希望能得到关于如何实现我想要做的事情的指导。

ActionExecutingContext.Controller
被声明为
Object
类型,因为框架没有对哪些类可以成为控制器施加任何限制

如果您总是创建从基本
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);
}

将context.Controller强制转换为Controller

尝试更改以下行

context.Controller.ViewBag.OptionsData = await optionsDataHelper.GetValueAsync(personId, CancellationToken.None);


我只是好奇@JasCav,我的回答有用吗?
((Controller)(context.Controller)).ViewBag.OptionsData = await optionsDataHelper.GetValueAsync(personId, CancellationToken.None);