I've got a form with a dropdownlist in my MVC app. Now that I'm trying to add validation to the mix it seems that a dropdownlist fails validation no matter what it's value is.
Without the validation it will allow the controller to work and redirect as planned. With the validation it does seem to allow the database changes to occur but ModelState.IsValid is false.
I'm stuck. Is this a known issue?
View:
<label for="parent">Child of:</label>
<%= Html.DropDownList("parent", (SelectList)ViewData["pageList"])%>
<%= Html.ValidationMessage("parent") %>
Controller action:
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
[ValidateAntiForgeryToken()]
public ActionResult Create(Page page)
{
try
{
pageRepository.Insert(page);
}
catch (RuleException ex)
{
ex.CopyToModelState(ModelState);
}
if (!ModelState.IsValid)
{
var pageSelectList = pageRepository.GetTop().ToList();
pageSelectList.Add(new Page
{
menuTitle = "None"
});
ViewData["pageList"] = new SelectList(pageSelectList.OrderBy(x => x.listOrder), "ID", "menuTitle");
return View();
}
return RedirectToAction("List");
}
The error returned is: The value 'x' is invalid. Where 'x' is the numeric value of the current selection. The failure occurs no matter what the chosen value is.
public class Page
{
private EntityRef<Page> _parent = default(EntityRef<Page>);
private EntitySet<Page> _children = new EntitySet<Page>();
public int ID { get; set; }
public string pageTitle { get; set; }
public string menuTitle { get; set; }
public string content { get; set; }
public int listOrder { get; set; }
public bool visible { get; set; }
public int parent { get; set; }
public DateTime? created { get; set; }
public DateTime? edited { get; set; }
public string createdBy { get; set; }
public string lastEditBy { get; set; }
public string linkInfo { get; set; }
public bool IsSelected { get; set; }
public Page Parent
{
// return the current entity
get { return this._parent.Entity; }
set { this._parent.Entity = value; }
}
public EntitySet<Page> Children
{
get { return this._children; }
set { this._children.Assign(value); }
}
public static Page Error404()
{
return (new Page
{
content = "<p>Page not found</p>",
pageTitle = "404. Page not found"
});
}
}
Here's what I tried for a workaround:
public ActionResult Create([Bind(Exclude="parent")] Page page)
{
page.parent = Convert.ToInt32(Request.Form["parent"]);
...
I just excluded the dropdownlist from the ModelBinding and reloaded it back in via the Request.Form. Is it good practice?
I ended up testing against ModelState["parent"].Value.AttemptedValue instead of the entity property which was nulling out at the attempt to put a string into an int?.
What's throwing the RuleException? I'm assuming you're using some sort of validation engine to determine whether the "parent" property is valid or not. I'd step through to see why this exception is being thrown. Maybe the value isn't passing into your controller action correctly or maybe your validation rules are different than what you think they are.