By default the MVC framework will create Controller actions such as Edit or Create with a FormCollection parameter;
1: public ActionResult Create(FormCollection collection)
The FormCollection inherits from a NameValueCollection and as such it’s items are accessed something like;
1: article.Title = collection["Title"];
2: article.Content = collection["Content"];
So where does “Title” and “Content” come from? These items, using convention, are created to represent the posting form’s HTML values;
1: <label for="Title">Title</label><br />
2: < %=Html.TextBox("Title")% >
This seems great for small forms but what about large forms? And what about when a form value id changes in the HTML then you must remember to change the action code too. Well this is a convention so there are trade offs!!
That said, the MVC team have made life even easier with the Bind attribute, so my action code looks like;
1: public ActionResult Create([Bind] Article article)
Under the hood the FormCollection items are matched to the Article properties and now my action receives a strongly typed Article object. This leaves convention remaining only in the HTML ids matching to the Article object’s property names.
Bind offers a number of properties to help with fine tuning the Model Binding. To highlight a few;
1: public ActionResult Create(
2: [Bind(Prefix = "NewArticle", Exclude = "Id")]
3: Article article)
Prefix sets the HTML control naming prefix used, more common in long forms which might have the same type of data such as business address and home address. To support the “NewArticle” prefix show above the HTML would look like;
1: <label for="Title">Title</label><br />
2: < %=Html.TextBox("NewArticle.Title")% >
Exclude sets the properties which are NOT allowed to be bound. So for actions such as Create, you want to ensure there is no possibility of the client setting the Id.
If you require any of Bind’s additional functionality and are simply writing code like;
1: public ActionResult Create([Bind] Article article)
Convention pops up again and in fact you don’t even have to specify [Bind], so the following code will also result in strongly typed parameter objects;
1: public ActionResult Create(Article article)
Just for clarity; To use strongly typed Model Binders you DO NOT have to have a strongly typed view.
Happy binding :) and back to the TDD & MVC Adventures landing page