views:

593

answers:

2

Im following the approch outlined here to do this.

Im having a problem with validating a dropdown selection with xval, the MVC binding seems to infer the wrong thing an allowing the operation to pass validation, but the modelstate stores the binding exception and makes the page invalid - so I get the situation where operation is allowed to execute with invalid data, but the page is invalid so the user is lead to believe validation failed.

This might make it clearer

This is my drop down, assume the user did nothing so "Please select" is selected.

  Do you like cheese:
     <select name="Favourites.Cheese">
         <option>Please Select</option>
        <option value="1">Yes</option>
        <option value="0">No</option>
     </select>
     <%=Html.ValidationMessage("Favourites.Cheese")%>

This is the Controller action the from posts too, MVC maps the value false to fav.cheese,

public ActionResult Create(Favourites fav)
{
            try
            {
                _favTask.Create(fav);
            }
            catch (RulesException ex)
            {
                ex.AddModelStateErrors(ModelState, "Favourites");
            }

            if(!ModelState.IsValid)
            {
                //redirect back
            }
            //other stuff
 }

The property has been attributed

 pulic class Favourites
    {
         [Required]
          public bool Cheese{get;set;}
    }

No exceptions are throw because fav.cheese has a value

public int Create(Favourites fav)
{

   var errors = DataAnnotationsValidationRunner.GetErrors(fav);
   if (errors.Any())
       throw new RulesException(errors);

       //create fav   
 }

But when focus returns to the controller ModelState.Isvalid comes out as false, so the from is reloaded with the message The value 'Please Select' is invalid. How do I stop this, from happening and how do I xVal driven validation method of "Please select a value"?

+1  A: 

If you want the user to be able to not select a value and infer false, then I would give your default selection a value of 0. This way there will be a value sent even if they don't choose one and the Required attribute will be satisfied.

<option value="0">Please Select</option>

EDIT: Based on your comments, I suggest some client-side validation using a client-side validation plugin -- like jQuery validation. This will allow you, in most cases, to give a suitable error message without having to actually post the request. On the server side, if the ModelState is invalid and that particular field is invalid, replace the error message with a more appropriate one. I wouldn't suggest changing the model just to accommodate binding framework.

tvanfosson
Mvc will map that to false no? thus it will appear something has been selected?
Dan
Did I misunderstand your question? You said that now they get a validation error "The value "Please Select" is invalid" and you wanted to stop the error? What do you want to happen instead?
tvanfosson
I want to display a message like "Please select a value" the current message is a by-product of MVC binding, not the xval validation no?
Dan
Re your edit that doesnt seem right - a validation framework that cant Handel dropdowns - and thus I have to rely on client side - manual replace - I hope there is a better way.
Dan
@Dan - The problem is that the value in the model has a correct value because a boolean must take on some value. You could make the field a nullable boolean, but that seems to be breaking the model to fit the validation framework. You could explicitly check that the field was supplied and set the model state manually, but why not just update the message?
tvanfosson
A: 

Boolean is a value type, so it will always have a value. [Required] therefore has no real effect. What happens if you use a Nullable<bool> instead? This should allow MVC to assign a null value if the first option is selected, and the Required attribute can then assert that the user did in fact select a value.

GalacticCowboy
Doing this doesn't help.
Dan