0

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?

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

7 Comments

That's just it. I wasn't testing for parent at all. It's a bound field in the model but there was no test to determine it's validity. I'm thinking that since it's defined as an int in the DomainModel and the value of a dropdownlist is always a string that may be the reason that it failed validation automatically during binding.
If that is the case how do I bind a DropDownList to an int?
You should paste your Page class so that we can see it. The fact that it's throwing a "RuleException" tells me you're using some sort of validation engine that will throw this when trying to save an invalid Page object to the database. In which case, you need to figure out what rule it's violating. Maybe there's a min/max value placed on it?
Yes, of course. Sorry about that. See the answer above, it won't fit in a comment.
Hmm...I'm still not sure where the RuleException is being thrown from. I'm guessing you have the validation checks in the pageRepository.Insert call? Have you tried stepping in and seeing where the exception is being thrown from? It has to be thrown from somewhere, otherwise your ModelState wouldn't be flagging as invalid.
|
0

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?.

1 Comment

I should also mention that I clear the model state: ModelState.Clear(); Then add the errors and the values back in place: ModelState.AddModelError(field, error); ModelState.SetModelValue(field, ValueProvider[field]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.