Reputation: 6402
How do I bind the SelectedItem to my Model using ModelBinding?
First I have Create a Simple model:
public class Element
{
public string Name { get; set; }
public int Value { get; set; }
}
public class MyModel
{
public Guid ContactID { get; set; }
public List<Element> Collection { get; set; }
public IEnumerable<SelectListItem> SelectList
{
get
{
return Collection.Select
(
e => new SelectListItem
{
Text = e.Name,
Value = e.Value.ToString()
}
);
}
}
public Element SelectedElement { get; set; }
}
Then in my Controller I initialize it :
public ActionResult Test()
{
var model = new MyModel {ContactID = Guid.NewGuid(), Collection = new List<Element>() };
var rand = new Random();
while (model.Collection.Count < 10)
{
var number = rand.Next(100);
model.Collection.Add(new Element {Value = number, Name = number.ToString()});
}
return View(model);
}
And Show it in my View:
@using (Html.BeginForm("TestPostBack", "Home"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MyModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.ContactID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ContactID, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Collection, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.SelectedElement, Model.SelectList)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
When pressing the submit button on my form I want to hit TestPostBack
on my controller. Thats no problem either. But how ho I fill out the SelectedElement
property in my model? I want it to be the value of the selected item from my drop down.
public ActionResult TestPostBack(MyModel model)
{
throw new NotImplementedException();
}
Upvotes: 0
Views: 27
Reputation: 56716
I don't think it will be straightforward to get the whole object back. Not impossible, just no easy. The problem here is that drop down, which corresponds to HTML select element, only posts back the selected value of the option, not the text. So one can potentially think of intercepting the form post request and adding the text there, but that feels a bit hacky.
Most direct approach is to get back the value only:
public class MyModel
{
...
public int SelectedElementValue { get; set; }
}
Html.DropDownListFor(model => model.SelectedElementValue, Model.SelectList)
And then by value look up the object among the elements. Hopefully he value is unique:
public ActionResult TestPostBack(MyModel model)
{
// load list of elements
Element selectedElement = //look up element by model.SelectedElementValue
}
Upvotes: 1