mvc3 validate input 'not-equal-to'

后端 未结 6 1499
滥情空心
滥情空心 2020-12-13 21:33

My forms have inputs with default helper text that guides the user on what to enter (rather than using labels). This makes validation tricky because the input value is never

相关标签:
6条回答
  • 2020-12-13 21:37

    You could make your ViewModel implement IValidatableObject and when implementing the Validate method (from IValidatableObject) add some logic to check the values of the properties e.g.

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
            var results = new List<ValidationResult>();
    
            if (Name == "Please enter your name...") 
                results.Add(new ValidationResult("You must enter a name");
    
            ...
            Enter other validation here
            ...     
    
            return results;
        }
    

    Now, when Model.IsValid is called in your controller, this bit of logic will be ran and will return validation errors as normal.

    0 讨论(0)
  • 2020-12-13 21:39

    Yes thats the right way to go. You should implement your own atribute and implement IClientValidatable.

    You could also have a required boolean value set initially to false as a hidden form field. When the user changes the textbox, set it to true.

    0 讨论(0)
  • 2020-12-13 21:49

    It took a little while since your question was asked, but if you still like data annotations, this problem can be easily solved using this library:

    [Required]
    [AssertThat("FieldA != 'some text'")]
    public string FieldA { get; set; }
    

    Above, the field value is compared with some pre-defined text. Alternatively, you can compare fields values with each other:

    [AssertThat("FieldA != FieldB")]
    

    ...and when the case of the strings being compared does not matter:

    [AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]
    
    0 讨论(0)
  • 2020-12-13 21:51

    To improve a little bit of @Darin Dimitrov answer, if you want to add messages from the resources using ErrorMessageResourceName and ErrorMessageResourceType, just add this to the to the Error message ErrorMessage = ErrorMessage ?? ErrorMessageString

    The ErrorMessageString will look for the localized version of error message that you set in the model using those parameters (ErrorMessageResourceName and ErrorMessageResourceType)

    0 讨论(0)
  • 2020-12-13 21:56

    Here's a sample illustrating how you could proceed to implement a custom validation attribute:

    public class NotEqualAttribute : ValidationAttribute, IClientValidatable
    {
        public string OtherProperty { get; private set; }
        public NotEqualAttribute(string otherProperty)
        {
            OtherProperty = otherProperty;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var property = validationContext.ObjectType.GetProperty(OtherProperty);
            if (property == null)
            {
                return new ValidationResult(
                    string.Format(
                        CultureInfo.CurrentCulture, 
                        "{0} is unknown property", 
                        OtherProperty
                    )
                );
            }
            var otherValue = property.GetValue(validationContext.ObjectInstance, null);
            if (object.Equals(value, otherValue))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            return null;
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = ErrorMessage,
                ValidationType = "notequalto",
            };
            rule.ValidationParameters["other"] = OtherProperty;
            yield return rule;
        }
    }
    

    and then on the model:

    public class MyViewModel
    {
        public string Prop1 { get; set; }
    
        [NotEqual("Prop1", ErrorMessage = "should be different than Prop1")]
        public string Prop2 { get; set; }
    }
    

    controller:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new MyViewModel
            {
                Prop1 = "foo",
                Prop2 = "foo"
            });
        }
    
        [HttpPost]
        public ActionResult Index(MyViewModel model)
        {
            return View(model);
        }
    }
    

    and view:

    @model MyViewModel
    
    <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
    <script type="text/javascript">
        jQuery.validator.unobtrusive.adapters.add(
            'notequalto', ['other'], function (options) {
                options.rules['notEqualTo'] = '#' + options.params.other;
                if (options.message) {
                    options.messages['notEqualTo'] = options.message;
                }
        });
    
        jQuery.validator.addMethod('notEqualTo', function(value, element, param) {
            return this.optional(element) || value != $(param).val();
        }, '');
    </script>
    
    @using (Html.BeginForm())
    {
        <div>
            @Html.LabelFor(x => x.Prop1)
            @Html.EditorFor(x => x.Prop1)
            @Html.ValidationMessageFor(x => x.Prop1)
        </div>
        <div>
            @Html.LabelFor(x => x.Prop2)
            @Html.EditorFor(x => x.Prop2)
            @Html.ValidationMessageFor(x => x.Prop2)
        </div>
        <input type="submit" value="OK" />
    }
    
    0 讨论(0)
  • 2020-12-13 21:57

    The ideal solutions is a custom Attribute where you specify minimum and maximum lengths as well as MustNotContain="Please enter your name...".

    0 讨论(0)
提交回复
热议问题