The site I am creating custom colors that can be set by the user (only on certain pages). I want to grab that data within an ActionFilterAttribute and set it in the ViewBag so I can then get the data in my _Layout.cshtml.
Here is my 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);
}
}
Unfortunately, I receive an error on ViewBag that states:
'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]
I'm pretty sure I'm not understanding something correctly about Filters and I would appreciate guidance on how to achieve what I am looking to do.
ASP.NET MVC - ViewBag The ViewBag in ASP.NET MVC is used to transfer temporary data (which is not included in the model) from the controller to the view. Internally, it is a dynamic type property of the ControllerBase class which is the base class of the Controller class. The following figure illustrates the ViewBag.
An action filter is an attribute that you can apply to a controller action -- or an entire controller -- that modifies the way in which the action is executed. The ASP.NET MVC framework includes several action filters: OutputCache – This action filter caches the output of a controller action for a specified amount of time.
We can create custom action filters for various reasons including but not limited to: To create a custom action filter, we need to perform the following tasks: OnActionExecuting – This method is called before a controller action is executed. OnActionExecuted – This method is called after a controller action is executed.
Internally, it is a dynamic type property of the ControllerBase class which is the base class of the Controller class. ViewBag only transfers data from controller to view, not visa-versa. ViewBag values will be null if redirection occurs.
ActionExecutingContext.Controller
is declared of type Object
since the framework doesn't impose any restriction on which classes can be controllers.
If you are always creating your controllers inheriting from the base Controller
class, then you can use that assumption in your filter and cast context.Controller
as 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";
}
If you cannot make that assumption, then you can use a similar approach inspecting the result in the context:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With