MVC5:客户端的自定义验证无效

时间:2014-01-15 10:47:21

标签: c# jquery asp.net-mvc validation

基于此链接here 我进行了自定义验证,与链接中的验证相同。 但对我来说,客户端验证不起作用。

这是我的验证器

public class AtLeastOneRequiredAttribute:ValidationAttribute,IClientValidatable
{
    private readonly string[] _properties;
    public AtLeastOneRequiredAttribute(params string[] properties)
    {
        _properties = properties;
    }

    protected override ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
    {
        if (_properties == null || _properties.Length < 1)
        {
            return null;
        }
        foreach (var property in _properties)
        {
            var propertyInfo = validationContext.ObjectType.GetProperty(property);
            if (propertyInfo==null)
            {
                return  new ValidationResult(string.Format("Unknown property {0}", property));
            }
            var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
            if (propertyValue is string && !string.IsNullOrEmpty(propertyValue as string))
            {
                return null;
            }
            if (propertyValue !=null)
            {
                return null;
            }
        }
        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule()
        {
            ErrorMessage = ErrorMessage,
            ValidationType = "atleastonerequired"
        };
        rule.ValidationParameters["properties"] = string.Join(",", _properties);
        yield return rule;
    }
}

这是模型     公共阶层人     {

    [AtLeastOneRequired("FirstName","LastName",ErrorMessage = "*At Least First Name or Last Name is required.")]
    public string FirstName { get; set; }

    public string LastName { get; set; }

}

这是 conroller

[HttpGet]
public ActionResult AddPerson(int contactId)
{
    _personRepository.AddPerson(contactId);
    ..
    return PartialView(person);
}

[HttpPost]
public ActionResult AddPerson(Person person)
{

    return Content("Success!");
}

最后是视图

@model WebApplication1.Models.Person


<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<script type="text/javascript">
    jQuery.validator.unobtrusive.adapters.add('atleastonerequired', ['properties'], function(options) {
        options.rules['atleastonerequired'] = options.params;
        options.messages['atleastonerequired'] = options.message;
    });
    jQuery.validator.addMethod('atleastonerequired', function(value, element, params) {
        var properties = params.defineProperties.split(',');
        var values = $.map(properties, function(property, index) {
            var val = $('#' + property).val;
            return val != '' ? val : null;
        });
        return values.length > 0;
    },'');
</script>


@using(Html.BeginForm("AddPerson","Person",FormMethod.Post))
{
    @Html.ValidationSummary(false)
    @Html.HiddenFor(m=>m.ContactId)
    <div class="label">First Name</div>
    <div class="input-block-level">@Html.TextBoxFor(m=>m.FirstName)@Html.ValidationMessageFor(m=>m.FirstName)</div>
    <br/>
    <div class="label">Last Name</div>
    <div class="input-block-level">@Html.TextBoxFor(m=>m.LastName)@Html.ValidationMessageFor(m=>m.LastName)</div>
    <button type="submit" class="btn-primary">Submit</button>
}

我还在web.config中将 clientvalidation设置为true。 有什么理由不工作? 当用户单击提交按钮而不填写任何信息时,我希望错误显示在客户端,但这不会发生,我会转发到控制器的 HttpPost 方法。

我注意到,鉴于jQuery.validator.addMethod('atleastonerequired', function(value, element, params)内部提供的链接,函数属性设置为var properties = params.propertynames.split(',');,但对我来说,VS2013中的智能感知不提供params.propertynames它有这两个选项params.definePropertiesparams.originalProperties

这就是它无法正常工作的原因吗? 我该怎么做才能使我的验证工作?

Edit1:呈现HTML

<script src="/Scripts/jquery-1.8.2.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>

<form action="/" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#partialDiv" id="form0" method="post" novalidate="novalidate">    <div class="input-block-level"><input data-val="true" data-val-required="*Search text cannot be empty" id="SearchString" name="SearchString" type="text" value="" class="valid"> <span class="field-validation-valid" data-valmsg-for="SearchString" data-valmsg-replace="true"></span> </div>
    <button type="submit" class="btn-info">Submit</button>                              
</form><div id="partialDiv">





<form action="/Person/AddPerson" method="post" novalidate="novalidate"><div class="validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div><input data-val="true" data-val-number="The field ContactId must be a number." data-val-required="The ContactId field is required." id="ContactId" name="ContactId" type="hidden" value="1055">    <div class="label">First Name</div>
    <div class="input-block-level"><input data-val="true" data-val-atleastonerequired="*At Least First Name or Last Name is required." data-val-atleastonerequired-properties="FirstName,LastName" id="FirstName" name="FirstName" type="text" value=""><span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span></div>
    <br>
    <div class="label">Last Name</div>
    <div class="input-block-level"><input id="LastName" name="LastName" type="text" value=""><span class="field-validation-valid" data-valmsg-for="LastName" data-valmsg-replace="true"></span></div>
    <button type="submit" class="btn-primary">Submit</button>
</form>


</div>
        <hr>
        <footer>
            <p>© 2014</p>
        </footer>
    </div>

Edit2:我在视图中将html.textboxfor更改为html.editorfor并删除了html.validationmessagefor但仍无效。

3 个答案:

答案 0 :(得分:0)

据我所知,你没有正确访问你的params对象。

尝试修改代码,使其如下所示:

var properties = params[0].properties.split(',');

此外,您以错误的方式访问输入字段值。 val不是jQuery属性。请改用val()

var val = $('#' + property).val();

答案 1 :(得分:0)

我猜您在提交表单时遇到JavasSript错误,因为您已将验证参数键更改为defineProperties

将您的jQuery.validator.addMethod更改为:

jQuery.validator.addMethod('atleastonerequired', function (value, element, params) {
    var properties = params.properties.split(',');
    var values = $.map(properties, function (property) {
        var val = $('#' + property).val();
        return val != '' ? val : null;
    });
    return values.length > 0;
}, '');

答案 2 :(得分:0)

jQuery.validator.unobtrusive.adapters.add('atleastonerequired', ['properties'], function(options) {
    options.rules['atleastonerequired'] = {
      properties : options.params.properties;
    }
    options.messages['atleastonerequired'] = options.message;
});
jQuery.validator.addMethod('atleastonerequired', function(value, element, params) {
    var properties = params.properties.split(',');
    var values = $.map(properties, function(property, index) {
        var val = $('#' + property).val();
        return val != '' ? val : null;
    });
    return values.length > 0;
},'');