brtb
brtb

Reputation: 2311

how to pass a parameter from action to ActionFilterAttribute code

i have ActionFilterAttribute like the following

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (something == 1) //i know there is no something variable
        { 
           // do something
        }
        base.OnActionExecuting(filterContext);
    }

}

as you can see in my code there is no variable named as something. but i want to use the variable named as something in my action.

    public ActionResult Index()
    {
        int something = 1;
        return View();
    }

    public ActionResult About()
    {
        int something = 2;
        return View();
    }

    public ActionResult Contact()
    {
        int something = 1;
        return View();
    }

Upvotes: 0

Views: 4626

Answers (5)

Satpal
Satpal

Reputation: 133403

I think what you need is OnActionExecuted. I have not tested.

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var something = Convert.ToInt32(filterContext.RouteData.Values["something"]);
        if(something == 1)
        {
            //do something
        }
        base.OnActionExecuting(filterContext);
    }
}

Upvotes: 1

Bastaspast
Bastaspast

Reputation: 1040

I use structuremap dependency injection to do that. See here some snippets:

namespace something.Infrastructure.ActionFilters {

  public class PlatformAuthorizeAttribute : AuthorizeAttribute
  {
      public IRepository<User> UserRepo { get; set; }

      public override void OnAuthorization(AuthorizationContext filterContext)
      {
          base.OnAuthorization(filterContext);

          if (WebSecurity.Initialized && filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              if (filterContext.HttpContext.User.IsInRole("Banned"))
              {
                  WebSecurity.Logout();
                  filterContext.Result = new RedirectToRouteResult(
                      new RouteValueDictionary
                          {
                            {"Controller", "Home"},
                            {"Action", "Banned"},
                            {"Area", ""}
                          });
              }
              UserRepo.Dispose();
              UserRepo = null;
          }  
      }
  }
}

And then initialize the following mapping in your IoC structuremap class:

public static class IoC
{
    public static IContainer Initialize()
    {
        ObjectFactory.Initialize(x =>
            {
                x.Scan(scan =>
                    {
                        scan.TheCallingAssembly();
                        scan.WithDefaultConventions();
                    });
                x.SetAllProperties(pset =>
                    {
                        pset.WithAnyTypeFromNamespace("something.Infrastructure.ActionFilters");
                        pset.OfType<IRepository<User>>();
                    });
            });
        return ObjectFactory.Container;
    }
}

I think this is the cleanest way to provide your action filters with properties. Note that in my example I used a custom AuthorizeAttribute. You will need to change this to ActionFilterAttribute and use the OnActionExecuting method override to access the properties.

Upvotes: 0

Nilesh
Nilesh

Reputation: 2691

You use ViewBag for this as well.

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewBag.SommeVariable = "Test";
    }

And in your action

    public ActionResult Index()
    {
        var variable = ViewBag.SommeVariable;
        return View();
    }

Upvotes: 0

Maksym Strukov
Maksym Strukov

Reputation: 2689

OnActionExecuting is called by the ASP.NET MVC framework BEFORE the action method executes. So it doesn't make sense to initialize your something variable in the action body. But still if you are going to override some method which is called AFTER the action method executes you can probably use ViewBag to init the variable in the controller and then get its value using filterContext.

Upvotes: 0

Varun K
Varun K

Reputation: 3638

Use HttpContext.Items

HttpContext.Items["something"] = 1;

In ActionFilter, you can access it as:

var something = (int)filterContext.HttpContext.Items["something"];

However, your example of action filter is OnActionExecuting; this will execute before any of your Index/About actions executes. So you should initialize 'something' somewhere else as per your needs (for example, inside controller's OnActionExecuting method).

Upvotes: -1

Related Questions