繁体   English   中英

ASP Net Core 3.1 自定义验证属性多

[英]ASP Net Core 3.1 Custom Validation Attribute Multiple

我有一个关于允许多个属性的自定义验证器的问题,我需要显示基于 DOB 的模态。 我在 AddValidation 方法中添加 data-val 属性时遇到问题,仅显示第一个属性的属性。

[AgeRange("ModalA", 0, 64, ErrorMessage = "Modal A Error")]
[AgeRange("ModalB", 65, 80, ErrorMessage = "Modal B Error")]
public override DateTime? DateOfBirth { get; set; }
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)]
public class AgeRangeAttribute : ValidationAttribute, IClientModelValidator
{
    public AgeValidationProperties ValidationProps { get; set; }
 
    public AgeRangeAttribute(string id, int yearMinimum, int yearMaximum)
    {
        //Init
        ValidationProps = new AgeValidationProperties()
        {
            YearMinimum = yearMinimum,
            YearMaximum = yearMaximum,
            Id = id
        };
 
    }
 
    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        //Logic for Valid
    }
   
    public void AddValidation(ClientModelValidationContext context)
    {
//UPDATE!!!!
        var attributes = context.ModelMetadata.ContainerMetadata
                                            .ModelType.GetProperty(context.ModelMetadata.PropertyName)
                                            .GetCustomAttributes(typeof(AgeRangeAttribute), false)
                                            .Cast<AgeRangeAttribute>();

            var props = attributes.Select(x => x.ValidationProps).ToList();
            var messages = attributes.Select(x => x.ErrorMessage).ToList();

            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-agerange", JsonConvert.SerializeObject(messages));

            MergeAttribute(context.Attributes, "data-val-agerange-props", JsonConvert.SerializeObject(props));
    }
}
 
public class AgeValidationProperties
{
  public int YearMinimum { get; set; }
  public int YearMaximum { get; set; }
  public string Id { get; set; }
}

我想根据 DataAnnotations 装饰器中添加的规则验证 DOB 属性,如果年龄低于 64 岁,客户端将显示 ModalA,如果年龄在 65 到 80 之间,将显示 ModalB,大于 80 是有效日期。

HTML 生成

您可以直接在AgeRangeAttribute中返回错误信息。

我做了一个简单的测试,你可以参考一下:

年龄范围属性:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)]
    public class AgeRangeAttribute : ValidationAttribute, IClientModelValidator
    {
        public AgeValidationProperties ValidationProps { get; set; }

        public int Year { get; }

        public AgeRangeAttribute(string id, int yearMinimum, int yearMaximum)
        {
            //Init
            ValidationProps = new AgeValidationProperties()
            {
                YearMinimum = yearMinimum,
                YearMaximum = yearMaximum,
                Id = id
            };

        }

        protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
        {
            if ((int)value < ValidationProps.YearMaximum) {
                return new ValidationResult(GetErrorMessage());
            }
            
            return ValidationResult.Success;
            //Logic for Valid
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-agerange", GetErrorMessage());

            var year = Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-agerange-props",year);
        }

        public string GetErrorMessage() 
        {
            if (ValidationProps.Id == "ModalA")
            {
                return "Your age is not valid because is lower than 64 years old";
            }
            else 
            {
                return "Your age is not valid because is between 65 and 80 years old.";
            }
        }

        private static bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }

            attributes.Add(key, value);
            return true;
        }
    }
    public class AgeValidationProperties
    {
        public int YearMinimum { get; set; }
        public int YearMaximum { get; set; }
        public string Id { get; set; }
    }

需要验证的属性:

[AgeRange("ModalA", 0, 64)]
[AgeRange("ModalB", 65, 80)]
public int Age { get; set; }

看法:

<div class="row">
    <div class="col-md-4">
        <form method="post" asp-action="Index">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="@Model.Age" class="control-label"></label>
                <input asp-for="@Model.Age" class="form-control" />
                <span asp-validation-for="@Model.Age" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Submit" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

结果:

在此处输入图像描述

在此处输入图像描述

希望这可以帮到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM