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中,您可以选择[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]*;
});