Today I faced a problem and I'm not able to get weather I understand something wrong about ASP.NET MVC (and possibly MVC in general) or I miss something about it's implementation.
So, I have a simple model hierarchy:
public class Child
{
public Child(int notId, bool isSelected, string text)
{
NotId = notId;
IsSelected = isSelected;
Text = text;
}
public Child(){}
// naming: just to make sure I do not mess with some
// conventional infrastructure
public int NotId { get; set; }
public bool IsSelected { get; set; }
public string Text { get; set; }
}
public class Parent
{
public List<Child> Children { get; set; }
}
Here is my HomeController
's Edit actions:
[HttpGet]
public ActionResult Edit()
{
var parent = new Parent
{
Children = new List<Child>
{
new Child(1, true, "a"),
new Child(2, false, "b")
}
};
return View(parent);
}
[HttpPost]
public ActionResult Edit(Parent parent)
{
parent.Children = new List<Child>
{
new Child(4, false, "c"),
new Child(5, true, "d")
};
return View(parent);
}
Hese is my Edit.aspx
view:
<!-- Standart HTML elements ommited -->
<% Html.BeginForm(); %>
<% for (var i = 0; i < Model.Children.Count; i++){%>
<div>
<%=Html.LabelFor(m => m.Children[i].IsSelected)%>
<%=Html.EditorFor(m => m.Children[i].IsSelected)%> <!-- lamda -->
<%=Html.CheckBoxFor(m => m.Children[i].IsSelected)%> <!-- lamda -->
<%=Html.CheckBox("A", Model.Children[i].IsSelected)%> <!-- simple -->
</div>
<% } %>
<input type="submit" value="Submit" />
<% Html.EndForm();%>
The point is that in Edit
(HttpGet) method I create Parent
instance with two child Child
elements having their IsSelected
properties set to true
and false
respectively. After form is submitted in Edit
(HttpPost) method I give my Parent
object a new children collection of two Child
elements with their IsSelected
properties set to false
and true
respectively (that is opposite from HttpGet method) and call View()
method to render my model.
But what I get after submit is checkboxes, rendered with Html.EditorFor()
and Html.CheckBoxFor()
do not changes their state. It looks like Html.EditorFor()
and Html.CheckBoxFor()
methods take data NOT from my model but from a posted form data.
Could someone please explain me what is going on here and why ASP.NET MVC refuses to render my model? Workarounds? Fixes to my code?
Thanks in advance.
P.S. I noticed this behavior in MVC2 and thought this was some kind of a bug, but when I tested this with MVC3 it did the same thing.
But what I get after submit is checkboxes, rendered with Html.EditorFor() and Html.CheckBoxFor() do not changes their state. It looks like Html.EditorFor() and Html.CheckBoxFor() methods take data NOT from my model but from a posted form data.
That's exactly what they do and that's by design. Html helpers first look at modelstate when binding values and then the model. If you want to change this behavior you could remove all the items from model state that you intend to modify in your controller action:
[HttpPost]
public ActionResult Edit(Parent parent)
{
ModelState.Remove("Children");
parent.Children = new List<Child>
{
new Child(4, false, "c"),
new Child(5, true, "d")
};
return View(parent);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With