1

In my view I have a check box and a text box if the check box is checked then I require the text box to be filled with some text. To do this I call

ModelState.AddModelError("item", "Please enter some text.");

only if the checkbox returns true and the text box isempty when my page re-displays I receive the proper message where I have

@Html.ValidationMessageFor(model => model.item)

but I would like the text to go away after a use types something in the text box, without the user having to hit submit like it does with data annotation. How can I fix this?

I'm using c# Asp.net 4 with entity framework 5

Bob
  • 1,065
  • 2
  • 16
  • 36
  • Can you please elaborate? What do you mean you want the text to go away? Do you mean when the user re-submits after entering valid data? – mayabelle Dec 10 '13 at 17:09
  • @mayabelle No I mean live just like regular data annotation works – Bob Dec 10 '13 at 17:11
  • did you enabled client side validations – qwr Dec 10 '13 at 17:12
  • @qwr yes that was set to true – Bob Dec 10 '13 at 17:18
  • @Bob use data annotations.see mayabelle added some example – qwr Dec 10 '13 at 17:22
  • @Bob check this link. Here is what you want to accomplish (checkbox button and textbox)with client side jscript code . http://www.codeproject.com/Articles/613330/Building-Client-JavaScript-Custom-Validation-in-AS – qwr Dec 10 '13 at 17:40

2 Answers2

4

ModelState.AddModelError is server-side validation, so the error message will not go away until you post to the server.

If you want the functionality you describe, you can define a custom validation attribute and apply it both client side and server-side. For example, you can define a "RequiredIf" custom validation attribute, which would make a field required if a certain other condition is met (in this case, if another property is true):

public class RequiredIfAttribute : RequiredAttribute
    {
        private String PropertyName { get; set; }
        private Object DesiredValue { get; set; }

        public RequiredIfAttribute(String propertyName, Object desiredvalue)
        {
            PropertyName = propertyName;
            DesiredValue = desiredvalue;
        }

        protected override ValidationResult IsValid(object value, ValidationContext context)
        {
            Object instance = context.ObjectInstance;
            Type type = instance.GetType();
            Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
            if (proprtyvalue.ToString() == DesiredValue.ToString())
            {
                 ValidationResult result = base.IsValid(value, context);
                return result;
            }
            return ValidationResult.Success;
        }
    }

Register it in your global.asax:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredAttributeAdapter);

Then you can use it like this:

public class YourModel {
    // This is the property tied to your checkbox
    public bool YourBooleanProperty { get; set; }

    [RequiredIf("YourBooleanProperty", true)]
    public string Item { get; set; }
}

You could also leverage the JQuery Validate plugin to perform the same conditional validation client-side.

mayabelle
  • 9,804
  • 9
  • 36
  • 59
  • your solution works well, but when I apply it to my model it wants to make the column required in the database, how to I get around this? – Bob Dec 11 '13 at 14:29
  • This is why view models and domain models should be kept separate. I would strongly recommend using a view model for display purposes, even if the properties are the same or similar, for the purpose of separation of concerns and to avoid problems like this. You can convert from your view model to your domain model in your controller or middle tier layer if you have one before writing to the database. – mayabelle Dec 11 '13 at 15:00
  • So you suggest making two a viewmodel the same as model then in the controller setting the actual model equal to the viewmodel? – Bob Dec 11 '13 at 15:11
  • You would have to copy the properties. You could use AutoMapper (https://github.com/AutoMapper/AutoMapper) to make this easier. Also, your view model and domain model don't necessarily have to be identical (and usually would not be) - your view model should be strictly what is needed for display purposes. See the answer to this question: http://stackoverflow.com/questions/6185508/confused-with-model-vs-viewmodel – mayabelle Dec 11 '13 at 15:26
2

Try with jquery, attach an eventListener to the field and remove the class CSS that MVC added to the field and hide the validation label

theLaw
  • 1,261
  • 2
  • 11
  • 23