views:

469

answers:

3

If I create an object in a Custom Action Filter in ASP.NET MVC in

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    DetachedCriteria criteria = DetachedCriteria.For<Person>();
    criteria.Add("stuff");

    // Now I need to access 'criteria' from the Action.....

}

is there any way I can access the object from the Action that is currently executing.

+1  A: 

You could use the HttpContext:

filterContext.HttpContext.Items["criteria"] = criteria;

And you can read it in the action:

[YourActionFilter]
public ActionResult SomeAction() 
{
    var criteria = HttpContext.Items["criteria"] as DetachedCriteria;
}
Darin Dimitrov
I was thinking about using HttpContext.Items[] and its an acceptable solution as it will be cleared out at the end of the request. I wasn't sure if there was a place I could store stuff that exists only for the duration of the action.
reach4thelasers
A: 

Set item in ViewData or of a viewmodel if you pass it as a parameter into your action. Here I set the property of a ViewModel

public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
     ViewModelBase viewModel = null;
     foreach (object parameter in filterContext.ActionParameters.Values)
     {
         if (parameter is ViewModelBase)
         {
             viewModel = (ViewModelBase)parameter;
             break;
         }
     }
     if(viewModel !=null)
     {
         viewModel.SomeProperty = "SomeValue";
     }
 }


    public ActionResult About(ViewModelBase model)
    {
      string someProperty= model.SomeProperty;
}

EDIT Here is the untyped version I think you prefer:

   public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewData.Add("TestValue", "test");

    }

       [FilterWhichSetsValue]
        public ActionResult About()
        {
            string test = (string)ViewData["TestValue"];
            return View();
        }
Malcolm Frexner
Thanks for your suggestion. My actions don't take ViewModelBase as a parameter though, and I would prefer not to introduce it just to solve my problem.
reach4thelasers
See the edited post for the untyped version. I would still use the first version. Maybe the parametername just sounds to bad. It can be any class and doesnt have to be the class of the typed view.
Malcolm Frexner
A: 

I would recommend putting it in the Route data.

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RouteData.Values.Add("test", "TESTING");
        base.OnActionExecuting(filterContext);
    }

    public ActionResult Index()
    {
        ViewData["Message"] = RouteData.Values["test"];

        return View();
    }
Chad Moran
How long does an item survive for in RouteData? I only need to keep the object for the duration of the currently executing action, or at the most for the current request, if this is how route data works then this is the answer otherwise HttpContext.Items is probably better.
reach4thelasers
RouteData is data related to the currently executing route (action). Think it as a container that represents the request url parsed and mapped according to your routing rules.
Neal