Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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
C# 如何在列表中的每个项目的属性上添加客户端不引人注目的验证,并一次性打印消息?_C#_Jquery_Asp.net Mvc_Validation_Unobtrusive Validation - Fatal编程技术网

C# 如何在列表中的每个项目的属性上添加客户端不引人注目的验证,并一次性打印消息?

C# 如何在列表中的每个项目的属性上添加客户端不引人注目的验证,并一次性打印消息?,c#,jquery,asp.net-mvc,validation,unobtrusive-validation,C#,Jquery,Asp.net Mvc,Validation,Unobtrusive Validation,我有一个视图模型: public class RatingsEditViewModel { [PropertyOnEveryItemInListRequired(Common.TranslationsEnums.DetailObjectRating.ValidationMessageRateEveryParameter, "Rating")] public List<ReviewCategoryViewModel> CategoryTypes { get; set;

我有一个视图模型:

public class RatingsEditViewModel
{
    [PropertyOnEveryItemInListRequired(Common.TranslationsEnums.DetailObjectRating.ValidationMessageRateEveryParameter, "Rating")]
    public List<ReviewCategoryViewModel> CategoryTypes { get; set; }
        = new List<ReviewCategoryViewModel>();
}
我创建了一个自定义属性和适配器来验证服务器端,如下所示:

    public class PropertyOnEveryItemInListRequiredAttribute : RequiredAttribute
    {
        private string errorMessage;
        private string propertyName;

        public PropertyOnEveryItemInListRequiredAttribute(int id, string propertyName)
        {
            this.errorMessage = Translations.Translator.GetTranslation(id);
            this.propertyName = propertyName;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule propertyOnEveryItemInListRequiredAttribute = new ModelClientValidationRule();
            propertyOnEveryItemInListRequiredAttribute.ErrorMessage = this.errorMessage;
            propertyOnEveryItemInListRequiredAttribute.ValidationType = "propertyoneveryiteminlistrequiredattribute";

            yield return propertyOnEveryItemInListRequiredAttribute;
        }

        public override bool IsValid(object value)
        {
            var list = value as IList;

            if (list != null)
            {
                foreach (var element in list)
                {
                    var property = element.GetType().GetProperty(this.propertyName);

                    if (property.PropertyType == typeof(int))
                    {
                        var intValue = (int)property.GetValue(element, null);

                        if (intValue == 0)
                        {
                            return false;
                        }
                        else
                        {
                            continue;
                        }
                    }

                }

                return true;
            }

            return false;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return this.IsValid(value) ? ValidationResult.Success : new ValidationResult(this.errorMessage);
        }
    }


    public class PropertyOnEveryItemInListRequiredAttributeAdapter : DataAnnotationsModelValidator<PropertyOnEveryItemInListRequiredAttribute>
    {
        public PropertyOnEveryItemInListRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, PropertyOnEveryItemInListRequiredAttribute attribute)
        : base(metadata, context, attribute)
        {
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            return this.Attribute.GetClientValidationRules(this.Metadata, this.ControllerContext);
        }
    }
我知道这可能不是最好的解决方案(看起来很糟糕),所以请随时发表评论

我已经在js中将该方法添加到validator中(它是一个虚拟的):

我需要验证用户在所有类别上的输入(他需要选择一个星(每个元素的评级值),但是如果他没有这样做,我只需要为整个列表编写一次验证消息,附加在所有类别的控件之后


未激发GetClientValidationRules,未填充data val属性,也未调用adapters的addMethod。是否有方法在不引人注目的验证中处理此问题?如果没有,处理此列表的客户端验证的最佳方法是什么?

是否将验证属性应用于复杂属性(
CategoryTypes
)但您的视图不会为
CategoryTypes
(也不应该)生成表单控件,因此无法获得客户端验证。为什么不在
int?Rating
(可空属性)上使用
[必需]
属性@StephenMuecke我只需要查看整个列表的验证消息一次(如果未填写)附加到列表中。我想使用我为后端创建的自定义属性。您建议我如何使用plz处理这种情况?您不能使用此属性访问客户端jquery验证库。您可以始终创建自己的脚本,该脚本在表单中激发。submit()`事件,该事件检查是否有任何值无效,如果是,则在DOM中显示消息(并在
评级的输入的
事件的
.keyup()
上删除该消息)
    public class PropertyOnEveryItemInListRequiredAttribute : RequiredAttribute
    {
        private string errorMessage;
        private string propertyName;

        public PropertyOnEveryItemInListRequiredAttribute(int id, string propertyName)
        {
            this.errorMessage = Translations.Translator.GetTranslation(id);
            this.propertyName = propertyName;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule propertyOnEveryItemInListRequiredAttribute = new ModelClientValidationRule();
            propertyOnEveryItemInListRequiredAttribute.ErrorMessage = this.errorMessage;
            propertyOnEveryItemInListRequiredAttribute.ValidationType = "propertyoneveryiteminlistrequiredattribute";

            yield return propertyOnEveryItemInListRequiredAttribute;
        }

        public override bool IsValid(object value)
        {
            var list = value as IList;

            if (list != null)
            {
                foreach (var element in list)
                {
                    var property = element.GetType().GetProperty(this.propertyName);

                    if (property.PropertyType == typeof(int))
                    {
                        var intValue = (int)property.GetValue(element, null);

                        if (intValue == 0)
                        {
                            return false;
                        }
                        else
                        {
                            continue;
                        }
                    }

                }

                return true;
            }

            return false;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return this.IsValid(value) ? ValidationResult.Success : new ValidationResult(this.errorMessage);
        }
    }


    public class PropertyOnEveryItemInListRequiredAttributeAdapter : DataAnnotationsModelValidator<PropertyOnEveryItemInListRequiredAttribute>
    {
        public PropertyOnEveryItemInListRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, PropertyOnEveryItemInListRequiredAttribute attribute)
        : base(metadata, context, attribute)
        {
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            return this.Attribute.GetClientValidationRules(this.Metadata, this.ControllerContext);
        }
    }
<div class="row evaluation-content modal-rating">
    @{
        for (var i = 0; i < Model.CategoryTypes.Count; i++)
        {
            <div class="col-xs-12 evaluation-row">

                @Html.HiddenFor(Model => Model.CategoryTypes[@i].Id)
                @Html.HiddenFor(Model => Model.CategoryTypes[@i].Name)

                <span class="name">@Model.CategoryTypes[i].Name: *</span>
                <div class="rating-control pull-right">

                    @{
                        for (var j = 10; j > 0; j--)
                        {
                            <span id="@j"><i class="fa fa-star"></i></span>
                        }
                    }

                </div>
                @Html.TextBoxFor(Model => Model.CategoryTypes[@i].Rating, new { @id = "rating-" + i.ToString(), @style = "visibility: hidden; width: 0; height: 0; margin: 0;" })
                @*@Html.ValidationMessageFor(Model => Model.CategoryTypes[i].Rating)*@

            </div>
        }
    }

    @Html.ValidationMessageFor(model => model.CategoryTypes)
</div>
<input type="submit" class="btn btn-primary" id="submitButton" />
$("#submitButton").on("click", function () {
    var evalContainer = $(".row .evaluation-content div.rating-control");

    for (var i = 0, div; div = evalContainer[i]; i++) {
        for (var j = 0, span; span = div.children[j]; j++) {
            if (span.className === "active") {
                $("#rating-" + i).val(span.id);
            }
        }
    }
});
$.validator.addMethod("propertyoneveryiteminlistrequiredattribute", function (value, element, params) {
    if (!isValueZero(value))
    {
        return true;
    } else {
        return false;
    }
});

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

function isValueZero(str) {
    return parseInt(str) == 0;
}