When posting a form and doing my own validation (no UpdateModel) the actions required are non intuitive and chatty.
This is caused by the way the dropdownlist finds its selected value.
When all is ok the value comes from ViewData["dropdownname"] but if the is a ModelError,
the value all of a sudden comes from ModelState, which is has no trivial way of adding modelstate values.
so when a form has two dropdownlist and one is not valid (according to my validation)
I have to populate viewdata for one and modelstate for the other.
why not always get the selected value from the ViewData. and use modelstate for the errors only
or put everything in modelstate regardless of errors.
Sample:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TestController : Controller
{
//
// GET: /Test/
public class Data
{
public List<Customer> Customers { get; set; }
}
public ActionResult Index()
{
//create 10 customers
var result = Enumerable.Range(1, 10).Select(i => new Customer() { Id = i, Name = "Name " + i }).ToList();
Data d = new Data();
d.Customers = result;
return View(d);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection form)
{
var result = Enumerable.Range(1, 10).Select(i => new Customer() { Id = i, Name = "Name " + i }).ToList();
Data d = new Data();
d.Customers = result;
//custom validation
int value = int.Parse(form["customer"]);
if (value > 5)
{
//when ModelState.AddModelError() dropdownlist renders the value from modelstate
ModelState m = new ModelState();
ValueProviderResult v = new ValueProviderResult(form["customer"], form["customer"], System.Threading.Thread.CurrentThread.CurrentCulture);
m.Value = v;
ModelState.Add("customer",m);
ModelState.AddModelError("customer", "don't like this one");
}
//when there is no modelstate error dropdownlist renders the value from viewdata
foreach (var item in form.AllKeys)
{
ViewData[item] = form[item];
}
return View(d);
}
}
In the view: (of type ViewPage<Namespace.Controllers.TestController+Data>
<%
Html.BeginForm();
var list = Model.Customers.Select(c =>
new
SelectListItem { Text = c.Name, Value = c.Id.ToString() });
medvjed
0 Points
8 Posts
Repopulate form is painfull
Jan 29, 2009 07:19 AM|LINK
When posting a form and doing my own validation (no UpdateModel) the actions required are non intuitive and chatty.
This is caused by the way the dropdownlist finds its selected value.
When all is ok the value comes from ViewData["dropdownname"] but if the is a ModelError,
the value all of a sudden comes from ModelState, which is has no trivial way of adding modelstate values.
so when a form has two dropdownlist and one is not valid (according to my validation)
I have to populate viewdata for one and modelstate for the other.
why not always get the selected value from the ViewData. and use modelstate for the errors only
or put everything in modelstate regardless of errors.
Sample:
public class Customer { public int Id { get; set; } public string Name { get; set; } } public class TestController : Controller { // // GET: /Test/ public class Data { public List<Customer> Customers { get; set; } } public ActionResult Index() { //create 10 customers var result = Enumerable.Range(1, 10).Select(i => new Customer() { Id = i, Name = "Name " + i }).ToList(); Data d = new Data(); d.Customers = result; return View(d); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult Index(FormCollection form) { var result = Enumerable.Range(1, 10).Select(i => new Customer() { Id = i, Name = "Name " + i }).ToList(); Data d = new Data(); d.Customers = result; //custom validation int value = int.Parse(form["customer"]); if (value > 5) { //when ModelState.AddModelError() dropdownlist renders the value from modelstate ModelState m = new ModelState(); ValueProviderResult v = new ValueProviderResult(form["customer"], form["customer"], System.Threading.Thread.CurrentThread.CurrentCulture); m.Value = v; ModelState.Add("customer",m); ModelState.AddModelError("customer", "don't like this one"); } //when there is no modelstate error dropdownlist renders the value from viewdata foreach (var item in form.AllKeys) { ViewData[item] = form[item]; } return View(d); } }In the view: (of type ViewPage<Namespace.Controllers.TestController+Data>
<%
Html.BeginForm();
var list = Model.Customers.Select(c => new SelectListItem { Text = c.Name, Value = c.Id.ToString() });Response.Write(Html.DropDownList(
"customer", list)); Response.Write(Html.DropDownList("customer2", list));%>
<input type="submit" value="Go" /><%
Html.EndForm();
%>
<%=Html.ValidationSummary() %>