1

问候我的朋友...

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

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

而且我有一个字段文本(“ParaQueUsaEstasPag”),仅在选中任何复选框时才需要...

    [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>
4

2 回答 2

2

在 Foolproof 中,您有 [RequiredIf(...)] 的这些选项:

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

我想,在你的情况下,“复选框”是一个定制的类。您必须创建一个自定义属性来验证这一点

或者...

您可以在此类上添加一个属性以返回布尔值并使用 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

于 2014-09-10T14:43:03.270 回答
0

我要做的是[Required]填写该字段并action检查是否选中了其中一​​个复选框。ModelState如果没有,您可以从before checks中删除特定的必需错误ModelState.IsValid

例子:

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]*;

});
于 2014-09-10T14:37:01.377 回答