Multifield required validation is not working in client side in MVC 5?

拈花ヽ惹草 提交于 2019-12-12 03:37:28

问题


I used to implement multi field required validation using this link MVC3 Validating Multiple Fields As A Single Property

But it did not work at my end.

Below is the code I used.

Javascript

    $.validator.addMethod('multifield', function (value, element, params) {
    var properties = params.propertyname.split(',');
    var isValid = false;
    var count = 0;
    for (var i = 0; i < properties.length; i++) {
        var property = properties[i];
        if ($('#' + property).val() != "") {
            count++;
        }
    }
    if (properties.length == count) {
        isValid = true;
    }
    return isValid;
}, '');

$.validator.unobtrusive.adapters.add('multifield', ['propertyname'], function (options) {
    options.rules['multifield'] = options.params;
    options.messages['multifield'] = options.message;
}
);

Class

  public class Customer
    {
       public string AreaCode { get; set; }
      [MultiFieldRequired(new string[2] { "AreaCode", "PhoneNumber" }, ErrorMessage = "Please enter a phone number")]
       public string PhoneNumber { get; set; }
    }

    public class MultiFieldRequiredAttribute : ValidationAttribute, IClientValidatable
{
    string propertyName;
    private readonly string[] _fields;

    public MultiFieldRequiredAttribute(string[] fields)
    {
        _fields = fields;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach (string field in _fields)
        {
            propertyName = field;
            PropertyInfo property = validationContext.ObjectType.GetProperty(field);
            if (property == null)
                return new ValidationResult(string.Format("Property '{0}' is undefined.", field));

            var fieldValue = property.GetValue(validationContext.ObjectInstance, null);

            if (fieldValue == null || String.IsNullOrEmpty(fieldValue.ToString()))
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        // The value we set here are needed by the jQuery adapter
        ModelClientValidationRule multifield = new ModelClientValidationRule();
        multifield.ErrorMessage = this.ErrorMessage;
        multifield.ValidationType = "multifield"; // This is the name the jQuery validator will use
        //"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
        multifield.ValidationParameters.Add("propertyname", string.Join(",", _fields));

        yield return multifield;
    }
}

View

@using (Html.BeginForm("Add", "Home", FormMethod.Post, new { @class = "form-inline" }))
    {


    <div class="editor-label">
        @Html.LabelFor(model => model.AreaCode)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.AreaCode)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.PhoneNumber)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.PhoneNumber)
        @Html.ValidationMessageFor(model => model.PhoneNumber)
    </div>
          <button type="submit" tabindex="19" class="form-control btn btn-primary" style="float: right; margin-left: 8px; margin-right: 10px;">Submit</button>
    }

回答1:


The answer you linked to and the code you have based it on does not make a lot of sense. Applying a validation attribute to your AreaCode property without including an associated @Html.ValidationMessageFor() is pointless.

If you want a validation message associated with PhoneNumber that will display a Please enter a phone number error if it's empty, and to display a Please also enter an Area Code if its not empty but the AreaCode value is, then you need an attribute that is applied only to the PhoneNumber property, and that attribute needs to accept a parameter for the other property name.

Model

public string AreaCode { get; set; }
[Required(ErrorMessage = "Please enter a phone number")]
[RequiredWith("AreaCode", ErrorMessage = "Please also enter an Area Code")]
public string PhoneNumber { get; set; }

Validation attribute

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class RequiredWithAttribute : ValidationAttribute, IClientValidatable
{
    private const string _DefaultErrorMessage = "The {0} is also required.";
    private readonly string _OtherPropertyName;

    public RequiredWithAttribute(string otherPropertyName)
    {
        if (string.IsNullOrEmpty(otherPropertyName))
        {
            throw new ArgumentNullException("otherPropertyName");
        }
        _OtherPropertyName = otherPropertyName;
        ErrorMessage = _DefaultErrorMessage;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(_OtherPropertyName);
            var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
            if (otherPropertyValue == null)
            {
                return new ValidationResult(string.Format(ErrorMessageString, _OtherPropertyName));
            }
        }
        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(_OtherPropertyName),
            ValidationType = "requiredwith",
        };
        rule.ValidationParameters.Add("dependentproperty", _OtherPropertyName);
        yield return rule;
    }
}

And add the following scripts

<script type="text/javascript">
    // General function to get the associated element
    myValidation = {
        getDependantProperyID: function (validationElement, dependantProperty) {
            if (document.getElementById(dependantProperty)) {
                return dependantProperty;
            }
            var name = validationElement.name;
            var index = name.lastIndexOf(".") + 1;
            dependantProperty = (name.substr(0, index) + dependantProperty).replace(/[\.\[\]]/g, "_");
            if (document.getElementById(dependantProperty)) {
                return dependantProperty;
            }
            return null;
        }
    }

    $.validator.addMethod("requiredwith", function (value, element, params) {
        var dependantControl = $('#' + params.dependentproperty);
        return dependantControl.val() !== '';
    });

    $.validator.unobtrusive.adapters.add("requiredwith", ["dependentproperty"], function (options) {
        var element = options.element;
        var dependentproperty = options.params.dependentproperty;
        dependentproperty = myValidation.getDependantProperyID(element, dependentproperty);
        options.rules['requiredwith'] = {
            dependentproperty: dependentproperty
        };
        options.messages['requiredwith'] = options.message;
    });

</script>



回答2:


If I m not wrong MultiFieldRequired is used above class name which was explain in below stackoverflow link earlier: MVC3 Validating Multiple Fields As A Single Property

You can also try below method in model.Also Add namespace in

model

=====================

using System.Web.Mvc; 

=====================

 public class Customer
    {
        //...other fields here
         [Remote("ValidateAreaPhoneNumber","Home",AdditionalFields="PhoneNumber",ErrorMessage="Please enter a phone number")]

        public string AreaCode { get; set; }

        public string PhoneNumber { get; set; }
    }

You may write the method named

ValidateAreaPhoneNumber

in ur

Home Controller

as below:

public JsonResult ValidateAreaPhoneNumber(string PhoneNumber)
{

    //True:False--- action that implement to check PhoneNumber uniqueness

      return false;//Always return false to display error message
}


来源:https://stackoverflow.com/questions/39325307/multifield-required-validation-is-not-working-in-client-side-in-mvc-5

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!