Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 集合上的MVC3客户端验证,至少有一个元素具有值_.net_Asp.net Mvc 3_Client Side Validation_Model Validation - Fatal编程技术网

.net 集合上的MVC3客户端验证,至少有一个元素具有值

.net 集合上的MVC3客户端验证,至少有一个元素具有值,.net,asp.net-mvc-3,client-side-validation,model-validation,.net,Asp.net Mvc 3,Client Side Validation,Model Validation,我的视图模型 Public Class ViewModel <SelectOne()> Public Property Collection As List(Of Item) End Class 现在,我想要的是确保使用客户端验证至少选中一个复选框。 我可以通过在项上设置自定义验证属性来实现这一点。选择属性并通过$.validator.unobtrusive.adapters.add()注册新适配器 但是我觉得属性应该位于ViewModel.Collection属性上,因为

我的视图模型

Public Class ViewModel
  <SelectOne()>
  Public Property Collection As List(Of Item)
End Class
现在,我想要的是确保使用客户端验证至少选中一个复选框。

我可以通过在
项上设置自定义验证属性来实现这一点。选择
属性并通过
$.validator.unobtrusive.adapters.add()注册新适配器

但是我觉得属性应该位于
ViewModel.Collection
属性上,因为在服务器端,我已经在使用此自定义验证验证集合的某个项是否已
Selected=True

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SelectOneAttribute
    Inherits ValidationAttribute

    Protected Overrides Function IsValid(value As Object, validationContext As ValidationContext) As ValidationResult

        Dim list As IList

        If value Is Nothing Then
            Return Nothing
        End If

        If TypeOf value Is IEnumerable Then
            list = CType(value, IList)
        Else
            list = New Object() {value}
        End If

        Dim count As Integer = (From item In list
                                From prop In item.GetType().GetProperties()
                                Let attributes = prop.GetCustomAttributes(GetType(RequireOneOrMoreIndicatorAttribute), False)
                                Where attributes.Count > 0
                                From attribute In attributes
                                Where attribute.TargetValue = prop.GetValue(item, Nothing)).Count()
        If count > 0 Then
            Return Nothing
        End If

        Return New ValidationResult(FormatErrorMessage(validationContext.DisplayName))
    End Function
End Class
这就是客户端验证

$.validator.unobtrusive.adapters.add("selectone", function (options) {
    options.rules["selectone"] = {};
    options.messages["selectone"] = options.message;
});

$.validator.addMethod("selectone", function (value, element, parameters) {

    var $el = $(element),
        name = $el.attr("name"),
        field = name.replace(/\[.*$/, "").replace(".", "_"),
        attr = name.replace(/^.*\./, ""),
        test = new RegExp(field + "\\[\\d\\]\." + attr);

    var inputs = $("input[id^=" + field + "]:not([disabled]):not([type=hidden])").filter("input[name$=" + attr + "]");

    for(var i = 0; i < this.errorList.length; i++) {
        var name = $(this.errorList[i].element).attr("name");

        // Do not write out the error more than once.
        if (test.test(name)) return true;
    }

    return inputs.length == 0 || inputs.filter(":checked:not([disabled])").val();
});
$.validator.unobtrusive.adapters.add(“selectone”),函数(选项){
options.rules[“selectone”]={};
options.messages[“selectone”]=options.message;
});
$.validator.addMethod(“selectone”,函数(值、元素、参数){
变量$el=$(元素),
名称=$el.attr(“名称”),
field=name.replace(/\[.*$/,“”)。replace(“.”,“”),
attr=name.replace(/^.\./,“”),
测试=新的RegExp(字段+“\\[\\d\\]\.”+attr);
变量输入=$(“输入[id^=“+field+”]:不([disabled]):不([type=hidden])))。过滤器(“输入[name$=”+attr+”]);
对于(var i=0;i
您正在创建将在客户端运行的自定义验证,但如果您希望在客户端运行,则必须为该自定义验证创建JQuery,然后将其添加到页面中

请参考以下链接

作出以下更改:-

1.您的视图模型:-

Public Class ViewModel
  <SelectOne()>
  <SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
  Public Property Collection As List(Of Item)
End Class
公共类视图模型
公共财产集合作为列表(项目的)
末级
  • 我的模型:-

    公共类项目 公共属性选择为布尔值 作为字符串的公共属性值 末级

  • 在视图中添加以下行:

    @Html.HiddenFor(x=>x.ItemCollection)

  • 4.然后您将运行视图并查看视图源,然后它将

    4.然后您将提交代码,然后它将运行客户端验证。添加调试器并调试它

    5.然后修改客户端脚本。 1.现在,您可以从每个复选框中提取值,并选中任何复选框,然后提交表单,否则显示结果

    6.还可以根据您的要求更改SelectOnePropertyAttribute

    7.对于服务器端,我已经在c#:-

    [AttributeUsage((AttributeTargets.Field | AttributeTargets.Property),AllowMultiple=false,Inherited=false)] 公共类SelectOneAttribute:ValidationAttribute { 公共字符串PropertyName{get;set;}

        protected override ValidationResult IsValid(object  value, ValidationContext validationContext)
        {
            bool boolVal = false;
            IList list;
            if (value == null)
            {
                return null;
            }
            if (value.GetType().Name == typeof(List<>).Name || value.GetType().Name == typeof(IList<>).Name)
            {
                list = (IList)value;
            }
            else
            {
                list = new object[] {value};
            }
            if (list.Count<0)
                return null;
    
            if ((from object item in list let propertyInfo = item.GetType().GetProperties() from info in propertyInfo where String.Equals(info.Name, PropertyName) && (bool)info.GetValue(item) == true select item).Any())
            {
                return null;
            }
    
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
    }
    
    protected override ValidationResult有效(对象值,ValidationContext ValidationContext)
    {
    布尔布尔瓦尔=假;
    IList列表;
    如果(值==null)
    {
    返回null;
    }
    if(value.GetType().Name==typeof(List).Name | | value.GetType().Name==typeof(IList.Name)
    {
    列表=(IList)值;
    }
    其他的
    {
    列表=新对象[]{value};
    }
    
    如果(list.Count这是您需要的吗?如果没有选中任何“myCheckbox”,它将阻止表单提交

    $(document).ready(function () {
        $('#submitButtonId').click(function (e) {
            if ($('input[name=myCheckbox]:checked').length == 0) {
                e.preventDefault();
                alert('Please choose at least one checkbox before continuing!');
            }
        });
    });
    

    我正在为您开发一个自定义验证解决方案。我讨厌VB,所以它将使用C#。如果这很酷,请告诉我。只是好奇,您是否希望能够准确定义要在ViewModel上选中哪个复选框?C#很好。我希望能够设置任何属性/值组合。不仅仅是布尔值。我已经给出了解决方案se检查一下,现在让我来..这对你很有帮助Hey..请检查答案..我给你的答案是什么?可能我的问题不清楚。我已经可以实现客户端和服务器端验证。但是我感觉我的解决方案(使用自定义验证属性并在项目上注册适配器。选定属性)不是最优的。我真的希望验证属性设置在列表属性上,而不是项的属性上。我理解,因为验证是您为属性标签编写的,所以请将您的自定义验证以及您编写的javascript发送给我,然后我可以为您提供解决方案。我现在拥有的代码是ks很好。但我真的需要另一个解决方案。一个仅适用于列表属性的解决方案(如果可能)。请共享该代码,然后我可以处理该代码,为您提供正确的代码。事实上,在我在问题中提交的代码中,此位是通过$.validator.addMethod()添加的。
    Public Class ViewModel
      <SelectOne()>
      <SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
      Public Property Collection As List(Of Item)
    End Class
    
        protected override ValidationResult IsValid(object  value, ValidationContext validationContext)
        {
            bool boolVal = false;
            IList list;
            if (value == null)
            {
                return null;
            }
            if (value.GetType().Name == typeof(List<>).Name || value.GetType().Name == typeof(IList<>).Name)
            {
                list = (IList)value;
            }
            else
            {
                list = new object[] {value};
            }
            if (list.Count<0)
                return null;
    
            if ((from object item in list let propertyInfo = item.GetType().GetProperties() from info in propertyInfo where String.Equals(info.Name, PropertyName) && (bool)info.GetValue(item) == true select item).Any())
            {
                return null;
            }
    
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
    }
    
    $(document).ready(function () {
        $('#submitButtonId').click(function (e) {
            if ($('input[name=myCheckbox]:checked').length == 0) {
                e.preventDefault();
                alert('Please choose at least one checkbox before continuing!');
            }
        });
    });