Reputation: 4116
I have the following ViewModel:
public class ViewModel
{
public Address Address {get;set;}
[DisplayName("State")]
public IEnumerable<SelectListItem> StateSelect { get; set; }
public string StateID { get; set; }
public ViewModel()
{
}
public ViewModel(Stuff s, IDataContext dc)
{
StateSelect = dc.States.ToList().Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
});
Address = s.Address;
}
And in my Edit View:
<div class="display-field">
@Html.DropDownListFor(model => model.Address.StateID, Model.StateSelect,)
@Html.ValidationMessageFor(model => model.StateSelect)
</div>
My controller:
public ActionResult Edit(int id)
{
var stuff = context.Stuff.Find(id);
if (stuff== null)
{
throw new Exception("Stuff not found.");
}
return View(new ViewModel(stuff, context));
}
[HttpPost]
public ActionResult Edit(ViewModel model)
{
try
{
if (ModelState.IsValid)
{
//deeper logic, adds to ModelState.AddModelError
if(stillNotValid)
return View(model)
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Now, in my Edit
view the dropdown list populates correctly. However, when I post to Edit
in my controller, my model always has a null StateSelect.
How can I make sure StateSelect is pushed to my Edit
post so that if there are validation errors I can re-populate the dropdown?
Upvotes: 0
Views: 330
Reputation: 8458
I would avoid persisting data across browser requests like this for variety of reasons
Having said that, you can implement some amount of data persistence in the form of hidden variables in cookies given it's small amount of data and used to track how your user ended on your form, or how much of a wizard user has completed etc.
Upvotes: 0
Reputation: 11964
To post StateSelect to controller, you must write its elements to hidden fields with special names (look at this how to do it). But you can refill this IEnumerable in controller action Edit after post. It will be right decision.
Upvotes: 0
Reputation: 6741
You need to put you collection inside the <form />
to post it to the server with request. In this case, most likely, you'll have to build markup "by hands" using hidden inputs or put your markup inside hidden block to hide it from user.
Are you sure you want to send this list back and forth only to have this collection in view model? There is another solution - send this list to the View in ViewBag and bind it in your Actions. This will keep you from <form />
modelling and reduce post request size.
Upvotes: 1