Foolproof MVC 5取消挂起验证

本文关键字:挂起 验证 取消 MVC Foolproof | 更新日期: 2023-09-27 18:21:32

Grettings我的朋友。。。

所以我在我的模型中设置了一组复选框:

    [DisplayName("Páginas Consultadas")]
    public List<CheckBoxes> PaginasConsultadas { get; set; }

我有一个字段文本("ParaQueUsEstasPag"),只有在选中任何复选框时才需要它。。。

    [DisplayName("¿Para que usa esta(s) página(s)?")]
    public string ParaQueUsaEstasPag { get; set; }

部分观点:

    <div class="col-lg-4" id="DivPagConsultadas">
        <span>@Html.LabelFor(model => model.PaginasConsultadas, @Html.DisplayNameFor(model => model.PaginasConsultadas))</span>
        @{
    for (int i = 0; i < Model.PaginasConsultadas.Count(); i++)
    {
        <div class="checkbox">
            <label>
                @Html.CheckBoxFor(model => model.PaginasConsultadas[i].ValorCheckBox) @Model.PaginasConsultadas[i].NombreCheckBox
            </label>
        </div>
            @Html.HiddenFor(model => model.PaginasConsultadas[i].valorRespuesta, new { @Value = @Model.PaginasConsultadas[i].valorRespuesta })
    }
        }
    </div>
</div>
<br />
<div class="row">
    <div class="col-lg-12">
        @Html.LabelFor(model => model.ParaQueUsaEstasPag, @Html.DisplayNameFor(model => model.ParaQueUsaEstasPag))
        @Html.TextAreaFor(model => model.ParaQueUsaEstasPag, 5, 1, new { @class = "form-control", placeholder = "Esta pregunta se responde con base en la respuesta de la pregunta anterior" })
        @Html.ValidationMessageFor(model => model.ParaQueUsaEstasPag)
    </div>
</div>
    <br />
<div class="row">
    <div class="col-lg-12">
        <button type="submit" class="btn btn-default" onclick="dispararPleaseWait()">Enviar Encuesta...</button>
    </div>
</div>

有一种使用Foolproof的模式(即[RequiredIf])?


更新:遵循Elad的想法,我的课程是下一个:

public class PagSeleccionadasValidation : ValidationAttribute, IClientValidatable
{
    //todo
    private readonly String _ChkPagSel;
    public PagSeleccionadasValidation(String ChkPagSel)
    {
        _ChkPagSel = ChkPagSel;
    }
    public string P {get; set;}
    protected override ValidationResult IsValid(object value, ValidationContext validationcontext)
    {
        if (value == null)
        {
            var PropertyInfo = validationcontext.ObjectType.GetProperty(_ChkPagSel);
            var Lista = (List<CheckBoxes>)PropertyInfo.GetValue(validationcontext.ObjectInstance, null);
            bool HayAlgunaCheck = Lista.Any(r => r.ValorCheckBox == true);
            if (HayAlgunaCheck)
            {
                return new ValidationResult(this.ErrorMessageString);
            }
            else
            {
                return ValidationResult.Success;
            }
        }
        return ValidationResult.Success;           
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.DisplayName),
            ValidationType = "valpagselecc"
        };
        rule.ValidationParameters["valpag"] = P;
        yield return rule;
    }
}

在名为"js-ValPagSel.js"的js中,我放了这个:

$.validator.unobtrusive.adapters.addSingleVal('valpagselecc', 'valpag');
$.validator.addMethod('valpagselecc', function (value, element, params) {
//var checkValue = [Find element via jquery from the params.checkpropertinputname];
if (value) {
    return false; // just for test
}
else {
    return false;
}

});

在视图中:

<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="/Scripts/blur.js"></script>
<script src="/Scripts/jquery-ui-1.11.1.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/Custom/JS-ValPagSel.js"></script>
<textarea class="form-control" cols="1" data-val="true" data-val-valpagselecc="El campo ¿Para que usa esta(s) página(s)? no es válido." data-val-valpagselecc-valpag="" id="ParaQueUsaEstasPag" name="ParaQueUsaEstasPag" placeholder="Esta pregunta se responde con base en la respuesta de la pregunta anterior" rows="5"></textarea>

Foolproof MVC 5取消挂起验证

在Foolproof中,您可以选择[RequiredIf(…)]:

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]

在你的例子中,"复选框"是一个类,我想是定制的。你必须创建一个自定义属性来验证这个

或者。。。

您可以在这个类上添加一个Property来返回布尔值,并使用RequiredIfTrue验证器。

public class Checkboxes {
    public bool IsAtLeastOneSelected
    {
        get{
            return PaginasConsultadas.Any(r => r.ValorCheckBox == [WHATEVER_VALUE MEANS_CHECKED]);
        }
    }
}

然后。。。

[RequiredIfTrue("IsAtLeastOneSelected")]
[DisplayName("¿Para que usa esta(s) página(s)?")]
public string ParaQueUsaEstasPag { get; set; }

您的ViewModel可能是这样的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
public class TestViewModel
{
    public List<Checkboxes> PaginasConsultadas { get; set; }
    [RequiredIfTrue("IsAtLeastOneSelected")]
    public string ParaQueUsaEstasPag { get; set; }
    //You dont put that on your view. 
    //This is just used with RequiredIfTrue data anotation attribute so the Validator checks for it
    public bool IsAtLeastOneSelected
    {
        get { return PaginasConsultadas.Any(r => r.ValorCheckBox); }
    }
}
public class Checkboxes
{
    //In order to check/uncheck you should use boolean for ValorCheckBox
    public bool ValorCheckBox { set; get; }
    public string NombreCheckBox { set; get; }
}

剩下的,你必须查看文档。您必须添加一些脚本才能使其工作。

http://foolproof.codeplex.com/RequireIf代码=http://foolproof.codeplex.com/SourceControl/latest#Foolproof/RequiredIf.cs

如果选中了其中一个复选框,我将使字段[Required]action处于选中状态。如果没有,您可以在检查ModelState.IsValid之前从ModelState中删除特定的所需错误。

示例:

if (Model.MyCheckBox.Checked)
{
   ModelState.Remove("CheckboxName");
}
if(ModelState.IsValid)
{
   //Do stuff...
}

由于您也需要客户端验证,我将添加另一个选项。可以使用自定义数据注释。您需要创建一个继承自ValidationAttribute并实现IClientValidatable的类。

public class RequiredIf : ValidationAttribute, IClientValidatable
{
    private string _checkPropertyName;
    public RequiredIf(string checkPropertyName)
    {
        _checkPropertyName = checkPropertyName;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //Get PropertyInfo object
        var phonePropertyInfo = validationContext.ObjectType.GetProperty(_checkPropertyName);
        //Get value from property
        bool checkValue = (bool)phonePropertyInfo.GetValue(validationContext.ObjectInstance, null);
        if(!checkValue)
           return new ValidationResult(this.ErrorMessageString);
        return null;
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule rule = new ModelClientValidationRule();
        rule.ErrorMessage = this.ErrorMessageString;
        rule.ValidationType = "requiredIf";
        rule.ValidationParameters.Add("checkpropertinputname", _checkPropertyName);
        yield return rule;
    }
}

这是一个简化的示例,但您可以按照以下步骤进行操作。您可以向构造函数传递任何您喜欢的内容,并通过反射从模型中提取所有数据,如示例所示。

在客户端,您需要以下JS:

$.validator.unobtrusive.adapters.add('requiredIf', ['checkpropertinputname'],
    function (options) {
        options.rules['requiredIf'] = options.params;
        options.messages['requiredIf'] = options.message;
    });
$.validator.addMethod('requiredIf', function (value, element, params) {
    var checkValue = *[Find element via jquery from the params.checkpropertinputname]*;
});