Hugo Delsing
Hugo Delsing

Reputation: 14163

MVC model binding keeps values NULL

I'm trying to get custom model binding to work, but for some reason the values aren't set. The code seems ligit when comparing it to working code, but still it doesnt bind. I guess it some trivial thing i'm missing.

Custom model:

//Cluster is from Entity Framework

//BaseViewModelAdmin defines:
public List<KeyValuePair<string, string>> MenuItems;
public IPrincipal CurrentUser = null;
public Foundation Foundation; //also from Entity Framework

public class AdminClusterCreateModel : BaseViewModelAdmin
{
    public Cluster Item;
    public AdminClusterCreateModel()
    {
        Item = new Cluster();
    }
}

The view form looks like:

@using (Html.BeginForm()) {
  @Html.ValidationSummary(true)

  <fieldset>
      <legend>Cluster</legend>

      <div class="editor-label">
          @Html.LabelFor(model => model.Item.Active)
      </div>
      <div class="editor-field">
          @Html.EditorFor(model => model.Item.Active)
          @Html.ValidationMessageFor(model => model.Item.Active)
      </div>


      <div class="editor-label">
          @Html.LabelFor(model => model.Item.Name)
      </div>
      <div class="editor-field">
          @Html.EditorFor(model => model.Item.Name)
          @Html.ValidationMessageFor(model => model.Item.Name)
      </div>

      <p>
          <input type="submit" value="Create" />
      </p>
  </fieldset>
}

And the controller:

[HttpPost]
public ActionResult Create(AdminClusterCreateModel model, FormCollection form)
{
    if(ModelState.IsValid) //true
    {
        var test = form["Item.Name"]; //Value is correct from form (EG: Test)
        UpdateModel(model);  //no error
    }

    //At this point model.Item.Name = null <--- WHY?

    return View(model);
}

Cluster on request

public partial class Cluster
{
    public Cluster()
    {
        this.Team = new HashSet<Team>();
    }

    public long Id { get; set; }
    public System.DateTime Created { get; set; }
    public System.DateTime Modified { get; set; }
    public bool Active { get; set; }
    public long FoundationId { get; set; }
    public string Name { get; set; }

    public virtual Foundation Foundation { get; set; }
    public virtual ICollection<Team> Team { get; set; }
}

Upvotes: 5

Views: 4424

Answers (2)

dan
dan

Reputation: 1954

This is a trivial and a corner case, yet if it might help someone:

If your model has a property, named model this to will cause the DefaultModelBinder to return a null.

public class VehicleModel
{
    public string Model { get; set; }
}

Upvotes: 0

shakib
shakib

Reputation: 5469

DefaultModelBinder works explicitly on 'Properties', not on 'Fields'

Changing public Cluster Item to public Cluster Item {get; set;} in AdminClusterCreateModel should do the trick.

public class AdminClusterCreateModel : BaseViewModelAdmin
{
    public Cluster Item {get; set;}

    public AdminClusterCreateModel()
    {
        Item = new Cluster();
    }
 }

Regards

Upvotes: 10

Related Questions