gpt4 book ai didi

asp.net-mvc - MVC3 验证 - 需要组中的一个

转载 作者:行者123 更新时间:2023-12-01 23:00:00 24 4
gpt4 key购买 nike

给定以下 View 模型:

public class SomeViewModel
{
public bool IsA { get; set; }
public bool IsB { get; set; }
public bool IsC { get; set; }
//... other properties
}

我希望创建一个自定义属性来验证至少一个可用属性是否为真。我设想能够将属性附加到属性并分配组名称,如下所示:

public class SomeViewModel
{
[RequireAtLeastOneOfGroup("Group1")]
public bool IsA { get; set; }

[RequireAtLeastOneOfGroup("Group1")]
public bool IsB { get; set; }

[RequireAtLeastOneOfGroup("Group1")]
public bool IsC { get; set; }

//... other properties

[RequireAtLeastOneOfGroup("Group2")]
public bool IsY { get; set; }

[RequireAtLeastOneOfGroup("Group2")]
public bool IsZ { get; set; }
}

我想在表单提交之前在客户端进行验证,因为表单中的值会发生变化,这就是为什么我宁愿尽可能避免使用类级属性。

这将需要服务器端和客户端验证来查找具有作为自定义属性参数传入的相同组名称值的所有属性。这可能吗?非常感谢任何指导。

最佳答案

这是一种继续进行的方法(还有其他方法,我只是举例说明一种与您的 View 模型相匹配的方法):

[AttributeUsage(AttributeTargets.Property)]
public class RequireAtLeastOneOfGroupAttribute: ValidationAttribute, IClientValidatable
{
public RequireAtLeastOneOfGroupAttribute(string groupName)
{
ErrorMessage = string.Format("You must select at least one value from group \"{0}\"", groupName);
GroupName = groupName;
}

public string GroupName { get; private set; }

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
foreach (var property in GetGroupProperties(validationContext.ObjectType))
{
var propertyValue = (bool)property.GetValue(validationContext.ObjectInstance, null);
if (propertyValue)
{
// at least one property is true in this group => the model is valid
return null;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}

private IEnumerable<PropertyInfo> GetGroupProperties(Type type)
{
return
from property in type.GetProperties()
where property.PropertyType == typeof(bool)
let attributes = property.GetCustomAttributes(typeof(RequireAtLeastOneOfGroupAttribute), false).OfType<RequireAtLeastOneOfGroupAttribute>()
where attributes.Count() > 0
from attribute in attributes
where attribute.GroupName == GroupName
select property;
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var groupProperties = GetGroupProperties(metadata.ContainerType).Select(p => p.Name);
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage
};
rule.ValidationType = string.Format("group", GroupName.ToLower());
rule.ValidationParameters["propertynames"] = string.Join(",", groupProperties);
yield return rule;
}
}

现在,让我们定义一个 Controller :

public class HomeController : Controller
{
public ActionResult Index()
{
var model = new SomeViewModel();
return View(model);
}

[HttpPost]
public ActionResult Index(SomeViewModel model)
{
return View(model);
}
}

和 View :

@model SomeViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

@using (Html.BeginForm())
{
@Html.EditorFor(x => x.IsA)
@Html.ValidationMessageFor(x => x.IsA)
<br/>
@Html.EditorFor(x => x.IsB)<br/>
@Html.EditorFor(x => x.IsC)<br/>

@Html.EditorFor(x => x.IsY)
@Html.ValidationMessageFor(x => x.IsY)
<br/>
@Html.EditorFor(x => x.IsZ)<br/>
<input type="submit" value="OK" />
}

剩下的最后一部分是注册适配器以进行客户端验证:

jQuery.validator.unobtrusive.adapters.add(
'group',
[ 'propertynames' ],
function (options) {
options.rules['group'] = options.params;
options.messages['group'] = options.message;
}
);

jQuery.validator.addMethod('group', function (value, element, params) {
var properties = params.propertynames.split(',');
var isValid = false;
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
if ($('#' + property).is(':checked')) {
isValid = true;
break;
}
}
return isValid;
}, '');

根据您的具体要求,代码可能会进行调整。

关于asp.net-mvc - MVC3 验证 - 需要组中的一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7247748/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com