Sunday, March 6, 2011

Can you explain to me the Action parameters for MVCs Controller methods?

Can someone explain to or link to an article that explains how the parameters passed into the action of a controller are populated? I understand the basic mapping when you have the Controller/Action/ID and the ID is passed in as a variable, if it doesn't convert to the type that you are asking for then it won't be passed in to that action.

However I have been looking at the MVCContrib sub controller code and there was the following example:

public ActionResult Index(FirstLevelSubController firstLevel)

I want to know how this parameter is being populated because as far as I know nothing is being passed in to populate this?

Let's say I created the following action which is the only action in the controller:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index(Task task, ToDoList list)

What would I be passed back and why? (I know I could do a quick test to find out if they did come back but that would make me non the wiser as to why.

Thanks

From stackoverflow
  • Generally, its a function of ControllerActionInvoker. Objects are passing into the action after they instantiated in custom ControllerActionInvoker implementation. For more info about how ControllerActionInvoker works take a look at ASP.NET MVC - ControllerActionInvoker: Part 1

    Also there is a feature called "model binding", that helps you to bind the request params to your objects, so in most cases you do not need to make your own ControllerActionInvoker implementation. Take a look at this: ASP.NET MVC model binding from ScottGu

  • First of all, the only way you'll get parameters passed to a method with the [AcceptVerbs(HttpVerbs.Get)] attribute is via query parameters. Example:

    http://localhost/Task/Index/?task=mytask&todolist=a,b,c,d
    

    Many of the action methods you see with complex parameters are called via post and would most likey be a candidate for [AcceptVerbs(HttpVerbs.Post)].

    Create the following sample method:

    public ActionResult Index(int id, FormCollection form)
    {
    
    }
    

    If you where to inspect the form collection you might have something like the following after a form post:

    form["name"] = "bob"
    form["city"] = "LA"
    form["state"] = "CA"
    form["zip"] = "90210"
    

    in this case asp.net mvc has simply parsed the form values and thrown them into the form collection object. Of course now you have to extract each parameter manually to access the values. Wouldn't it be nice if there was way that asp.net mvc would handle that process for you? If you had the following class:

    public class User
    {
        string string Name {get; set;}
        string string City {get; set;}
        string string State {get; set;}
        string string Zip {get; set;}
    }
    

    and added that to your action method

    public ActionResult Index(int id, User user)
    

    asp.net mvc will use reflection to popuplate the user parameter prior to calling your action method. In effect it is doing the following, for each key in the form collection it it uses reflection to locate that property om the list of parameters declared in your action method. If it finds a property that matches it will attempt to set it's value.

    user.Name = form["name"]
    user.City = form["city"]
    user.State = form["state"]
    user.Zip = int.Parse(form["zip"])
    

    However, the id value gets set from the routing values as opposed to the form collection.

0 comments:

Post a Comment