HoopSnake
HoopSnake

Reputation: 736

MVC Custom Validation Attribute being overwritten by Default ModelValidater..The Value "null" is not valid

I have a model with some bool objects

    [DisplayName("Is student still at school")]
    //[ValidBoolDropDown("IsStillAtSchool")]
    public bool? IsStillAtSchool { get; set; }

that are being implemented with some bool editor dropdown templates

    @model bool?
@{
    int intTabIndex = 1;
    if (ViewData["tabindex"] != null)
    {
        intTabIndex = Convert.ToInt32(ViewData["tabindex"]);
    }
 }

 @{
    string strOnChange = "";
    if (ViewData["onchange"] != null)
    {
        strOnChange = ViewData["onchange"].ToString();
    }
}

<div class="editor-field">
    @Html.LabelFor(model => model): 

   @Html.DropDownListFor(model => model, new SelectListItem[] { new SelectListItem() { Text = "Yes", Value = "true", Selected = Model == true ? true : false }, new SelectListItem() { Text = "No", Value = "false", Selected = Model == false ? true : false }, new SelectListItem() { Text = "Select", Value = "null", Selected = Model == null ? true : false} }, new { @tabindex = intTabIndex, @onchange = strOnChange })

    @Html.ValidationMessageFor(model => model)
</div>

On the post I still get the default model validation error

The value 'null' is not valid for Is studentstill at school.(aka IsStillatSchool)

I have even implemented a custom ValidationAttribute

public class ValidBoolDropDown : ValidationAttribute
{
    public ValidBoolDropDown(string dropdownname) :base("Please Select for {0}")
    {

        DropDownName = dropdownname;
    }

    private string DropDownName;

    protected override ValidationResult IsValid(object value,ValidationContext validationContext)
    {


        var boolres = GetBool(validationContext);

        //if (!boolres.HasValue)
        //{
        //    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        //}

        return ValidationResult.Success;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name);
    }
    protected bool? GetBool(ValidationContext validationContext)
    {
        var propertyInfo = validationContext
                              .ObjectType
                              .GetProperty(DropDownName);
        if (propertyInfo != null)
        {
            var boolValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
            if (boolValue == null)
                return null;
            return boolValue as bool?;
        }
        return null;
    }
}

This fires but gets overwritten and the Model.Value.Error for this attribute still fails

I saw some about the turning the automatic required flag off for value types in Glocal.asx

  DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

but this has not worked..is it a case to create a custom MetadataValidatorProvider for the app or is there something else going on

Thanks in Adavance

Upvotes: 1

Views: 1311

Answers (1)

HoopSnake
HoopSnake

Reputation: 736

Ok so the problem was in the dropdown template for the line

  @Html.DropDownListFor(model => model, new SelectListItem[] { new SelectListItem() { Text = "Yes", Value = "true", Selected = Model == true ? true : false }, new SelectListItem() { Text = "No", Value = "false", Selected = Model == false ? true : false }, **new SelectListItem() { Text = "Select", Value = "null", Selected = Model == null ? true : false}** }, new { @tabindex = intTabIndex, @onchange = strOnChange })

With

new SelectListItem() { Text = "Select", Value = "null", Selected = Model == null ? true : false}

being the probelm Selectlistitem

When the default model binder tries to bind the form data back to the model the string "null" is not equal to null (empty object)

Once this is changed to

new SelectListItem() { Text = "Select", Value = ""}

Everything work happily and the Validation attrribute gets to do its job

Thanks to

ASP.NET MVC: DropDownList validation

:D

Upvotes: 1

Related Questions