Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set ViewBag from ActionFilterAttribute

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.

like image 733
JasCav Avatar asked Mar 14 '16 21:03

JasCav


People also ask

What is viewbag in ASP NET MVC?

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.

What is an action filter in MVC?

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.

How do I create a custom action filter?

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.

What is viewbag in Salesforce controller?

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.


1 Answers

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);
}
like image 124
Daniel J.G. Avatar answered Nov 10 '22 22:11

Daniel J.G.