加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

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

发布时间:2020-12-15 19:21:25 所属栏目:asp.Net 来源:网络整理
导读:给定以下viewmodel: public class SomeViewModel{ public bool IsA { get; set; } public bool IsB { get; set; } public bool IsC { get; set; } //... other properties} 我希望创建一个自定义属性,验证至少一个可用属性为true。我想象能够附加一个属性
给定以下viewmodel:
public class SomeViewModel
{
  public bool IsA { get; set; }
  public bool IsB { get; set; }
  public bool IsC { get; set; } 
  //... other properties
}

我希望创建一个自定义属性,验证至少一个可用属性为true。我想象能够附加一个属性到一个属性,并像这样分配一个组名:

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; }
}

我想在客户端验证在表单提交之前作为表单更改的值,这就是为什么我喜欢避免类级属性(如果可能的话)。

这需要服务器端验证和客户端验证,以定位所有具有相同组名称值的属性作为自定义属性的参数传入。这可能吗?任何指导是非常赞赏。

解决方法

这里有一种方法继续(还有其他方法,我只是说明一个将匹配您的视图模型是):
[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;
    }
}

现在,让我们定义一个控制器:

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

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

和一个视图:

@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;
},'');

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读