Today I was experiencing a problem in the MVC application I am currently developing.

First some information:

Model: ContactDataModel
ContactDataModel implements interface IContactData. This is because the related typedview Step1 contains a partialView that inherits IContactData.
this way we can reuse the partial view simply by having each model, that needs to use the partialview, implement this interface.

 

Interface IContactData


public interface IContactData
{
    ContactData Contact { get; set; }
}

 

Object ContactData


public class ContactData
{
    [Required]
    [StringLength(200)]
    public string Voornaam { get; set; }
}

 

View: Step1
This view inherits from ContactDataModel


...
<h2>ContactGegevens</h2>  
<% Html.RenderPartial("ContactDataUserControl"); %>
...

 

Partial View: ContactDataUserControl
This view inherits from IContactData


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<QNH.Interfaces.IContactData>" %>
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
    <legend>Fields</legend>
    <p>
        <label for="Contact.Voornaam">
            Voornaam:</label>
        <%= Html.TextBox("Contact.Voornaam")%>
        <%= Html.ValidationMessage("Contact.Voornaam", "*")%>
    </p>
.........more fields....form closed

 

Controller: MyController


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Step1( ContactDataModel contact )
{
    ....
}

 

The "POST" method "Step1" on MyController was recieving an empty ContactDataModel object. If I changed the the Step1 method to recieve the FormCollection instead of the Model object then my values would be present. After this I thought: what object is responsible for mapping the formvalues in my view to my model object. The answer is: the ComplexModelBinder.

The main thing to remember when using the ComplexModelBinder is the naming convention of your controls in the form. Because it uses reflection the ComplexModelBinder is expecting the Class Name + “.“ to be appended to the property name. If you are using the ComplexModelBinder and not prefixing the Class Name to the name of the Property, you will just get null values for your properties.

This means that in my partial view were I was using Contact.Voornaam I needed to use ContactData.Voornaam.This also means that I needed to change the name of the property in my interface to ContactData, because else it would not be recognised.

New Interface: IContactData:


public interface IContactData
{
    ContactData ContactData { get; set; }
}

New Partial View: ContactDataUserControl
This view inherits from IContactData


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<QNH.Interfaces.IContactData>" %>
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
    <legend>Fields</legend>
    <p>
        <label for="ContactData.Voornaam">
            Voornaam:</label>
        <%= Html.TextBox("ContactData.Voornaam")%>
        <%= Html.ValidationMessage("ContactData.Voornaam", "*")%>
    </p>
.........more fields...form closed
 

 

I really hope this helps out someone else. Happy Coding.