Let's say I have a City table in SQL server. This is the HomeController:
[HttpGet]
public ActionResult Index()
{
SampleDBContex db = new SampleDBContex();
return View(db.Cities);
}
[HttpPost]
public string Index(IEnumerable<City> cities)
{
if (cities.Count(x => x.IsSelected) == 0)
{
return "You didn't select city";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected -");
foreach (City city in cities)
{
if (city.IsSelected)
{
sb.Append(city.Name + ", ");
}
}
sb.Remove(sb.ToString().LastIndexOf(","), 1);
return sb.ToString();
}
}
}
and this is index view (get method):
@model IEnumerable<Part38MVCCheckBoxList.Models.City>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.EditorForModel()
<br />
<input type="submit" value="Submit" />
}
and this is the editor template:
@model Part38MVCCheckBoxList.Models.City
@Html.HiddenFor(x => x.ID)
@Html.HiddenFor(x => x.Name)
@Html.CheckBoxFor(x => x.IsSelected)
@Html.DisplayFor(x => x.Name)
I don't understand why do we need to use @Html.HiddenFor(x => x.Name), otherwise it couldn't display city name.I think we pass the model IEnumerable so we should have cityname existed already when we retrieve them from database
You need a hiddenfor because HTTP messaging is stateless, so if you'd get an object from a controller it will have the complete object on your page but if you'd send everything back except your Name and Id variable as inputs with values on your form it will be lost.
Your controller will only retain it as long as it's needed and after your HttpGet answer from the controller the controller is done and it will no longer retain that value.
I too feel it's counter intuitive, but this is how HTTP protocol is built.