9

I have the following:

 public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        var model = filterContext.Controller.ViewData.Model as BaseViewModel;

        if (model == null)
        {
            model = new BaseViewModel();
            filterContext.Controller.ViewData.Model = model;
        }

        model.User = (UserPrincipal)filterContext.HttpContext.User;
        model.Scheme = GetScheme();
    }

Now stepping through that i can see the user and scheme on the model are being populated.

By the time I get to the action however they are both null?

What am i doing wrong here?

And adding to this, is this the proper way of adding to the model?

Here is the controller code:

[InjectStandardReportInputModel]
public ActionResult Header(BaseViewModel model)
{
    //by this point model.Scheme is null!!

}
  • Could you also post your `Controller` code? You sure you've added the `attribute` to the `class` definition or the applicable `action`/s? – Alex Feb 09 '12 at 17:10
  • added action code - are you saying this should be working?... –  Feb 09 '12 at 17:12
  • The same issue is discussed here http://stackoverflow.com/questions/4766156/all-viewmodels-inherit-from-baseviewmodel-can-i-set-this-up-in-onactionexecut – Andrei Schneider Feb 09 '12 at 17:19

2 Answers2

7

Controller.ViewData.Model is not populating action parameters in asp.net mvc. That property is used to pass data from action to view.

If for some reason you do not want to use custom Model Binder (which is the standard, reccommended way of populating action parameters in asp.net-mvc), you could you ActionExecutingContext.ActionParameters Property

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.ActionParameters["model"] = new BaseViewModel();
        // etc
    }
archil
  • 39,013
  • 7
  • 65
  • 82
  • 1
    i really hate to admit it but for others making the same mistake: I actually started out using this method, and when i added the attribute to another action it stopped working. the reason? I had named my model "input" on this action! i now have a check and throw if the attribute is added to an action with an incorrectly named model :) –  Feb 10 '12 at 10:43
  • @iwayneo why wouldn't you use custom Model Binder? – archil Feb 10 '12 at 11:45
1

Bit late for the reply but it will be useful for others. we can get the value of model in OnActionExecuting by just decoration our attribute a little more.

THIS IS OUR FILTER CLASS

public sealed class TEST: ActionFilterAttribute
{

   /// <summary>
    /// Model variable getting passed into action method
    /// </summary>
    public string ModelName { get; set; }

    /// <summary>
    /// Empty Contructor
    /// </summary>
    public TEST()
    {
    }

    /// <summary>
    /// This is to get the model value by variable name passsed in Action method
    /// </summary>
    /// <param name="modelName">Model variable getting passed into action method</param>
    public TEST(string modelName)
    {
        this.ModelName = modelName;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var result = filterContext.ActionParameters.SingleOrDefault(ap => ap.Key.ToLower() == ModelName.ToString()).Value;
    }

}

    THIS IS OUR ACTION METHOD PLEASE NOTE model variable has to be same
    [HttpPost]
    [TEST(ModelName = "model")]
    public ActionResult TESTACTION(TESTMODEL model)
    {
    }

AND THATS IT.....PLEASE VOTE IF YOU LIKE THE ANSWER

Atul Chaudhary
  • 3,698
  • 1
  • 31
  • 51