Use View Models instead of FormCollection

I have recently been spending quite a bit of time on StackOverflow and I noticed that quite a few of the MVC-related answers make use of the FormCollection class.  If you’re unfamiliar with this class, here is an example of how it gets used:

<% using (Html.BeginForm("Add", "Contacts", FormMethod.Post)) { %>

    <label for="Name">Name:</label><input type="text" name="Name" /><br />
    <label for="Surname">Surname:</label><input type="text" name="Surname" /><br />
    <label for="CellNumber">Cellphone Number:</label><input type="text" name="CellNumber" /><br />

    <input type="submit" value="Add" />

<% } %>    
public ActionResult Add(FormCollection formValues)
{
    var contact = new Contact();

    contact.Name = formValues["Name"];
    contact.Surname = formValues["Surname"];
    contact.CellNumber = formValues["CellNumber"];

    service.Add(contact);

    return RedirectToAction("Index");
}

Which of course works exactly as expected.  Let’s take a look at the same example using a view model.

public class ContactViewModel
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string CellNumber { get; set; }
}
public ActionResult Add(ContactViewModel viewModel)
{
    var contact = new Contact();

    contact.Name = viewModel.Name;
    contact.Surname = viewModel.Surname;
    contact.CellNumber = viewModel.CellNumber;

    service.Add(contact);

    return RedirectToAction("Index");
}

Which I think is a lot neater (plus no magic strings).  I find that this approach is much easier to test and maintain.

Keep in mind that you can even create your own model binder for specifying how the form values should bind to the view model.  (More on this in a later post).  However in most cases the default model binder should be sufficient.

Happy coding.