繁体   English   中英

如何使用由 model 属性组成的参数创建自定义验证属性

[英]How to create a custom validation attribute with parameters consisting of model properties

我目前正在尝试在 asp.net 内核上创建一个站点。 当我按下提交按钮时,如果输入不正确,我希望所有验证消息都出现。

在此处输入图像描述

现在,我有使用“asp-validation-for=Client.Name”和Client.ContactNumber 的姓名和电话号码验证消息。 现在我希望能够从服务器端验证用户是否至少选中了一个框,或者填写了“其他”字段。 所以我试图看看我是否可以制作一个自定义属性来验证它但没有得到任何运气。 我已尝试发送客户端 class 的属性,但它会引发错误,提示“非静态字段、方法或属性‘客户端’需要 object 引用。”。 我也尝试过CS0120 的最佳解决方案:非静态字段、方法或属性 'foo' 需要一个 object 引用,但我认为在我的情况下这些解决方案是不可能的。

我正在使用的文件的代码如下

Client.cs 的代码(模型类)

public class Client
{
    //some attributes

    [Required]
    public string Name { get; set; }

    [Required]
    [DisplayName("Bookkeeping")]
    public bool Bookkeeping { get; set; }

    [Required]
    [DisplayName("Personal Income Taxation")]
    public bool Personal_Income_Taxation { get; set; }

    [Required]
    [DisplayName("Self-Employed Business Taxes")]
    public bool Self_Employed_Business_Taxes { get; set; }

    [Required]
    [DisplayName("GST/PST/WCB Returns")]
    public bool GST_PST_WCB_Returns { get; set; }

    [Required]
    [DisplayName("Tax Returns")]
    public bool Tax_Returns { get; set; }

    [Required]
    [DisplayName("Payroll Services")]
    public bool Payroll_Services { get; set; }

    [Required]
    [DisplayName("Previous Year Filings")]
    public bool Previous_Year_Filings { get; set; }

    [Required]
    [DisplayName("Govt. Requisite Form Applicaitons")]
    public bool Government_Requisite_Form_Applications { get; set; }

    public string Other { get; set; }

    [CheckboxAndOtherValidation(bookkeeping: Bookkeeping,
        personal_Income_Taxation: Personal_Income_Taxation,
        self_Employed_Business_Taxes: Self_Employed_Business_Taxes,
        gST_PST_WCB_Returns: GST_PST_WCB_Returns,
        tax_Returns: Tax_Returns,
        payroll_Services: Payroll_Services,
        previous_Year_Filings: Previous_Year_Filings,
        government_Requisite_Form_Applications: Government_Requisite_Form_Applications,
        other: Other)]
    public bool AreCheckboxesAndOtherValid { get; set; }

FreeConsultation.cshtml(查看页面)

 <div class="container" style="padding:30px;"> <br /> <h1 class="text-info">Create New Client</h1><br /> <form method="post"> <div class="text-danger" asp-validation-summary="ModelOnly"></div> <div class="form-group row"> <div class="col-3"> <label asp-for="Client.Name"></label> </div> <div class="col-6"> <input type="text" asp-for="Client.Name" class="form-control" /> </div> <span class="text-danger col-3" asp-validation-for="Client.Name"></span> </div> <!-- More code -->

我为自定义验证属性创建的实用程序 class - CheckboxAndOtherValidation.cs

    public class CheckboxAndOtherValidation : ValidationAttribute
{
    private readonly bool Bookkeeping;
    private readonly bool Personal_Income_Taxation;
    private readonly bool Self_Employed_Business_Taxes;
    private readonly bool GST_PST_WCB_Returns;
    private readonly bool Tax_Returns;
    private readonly bool Payroll_Services;
    private readonly bool Previous_Year_Filings;
    private readonly bool Government_Requisite_Form_Applications;
    private readonly string Other;

    public CheckboxAndOtherValidation(bool bookkeeping,
        bool personal_Income_Taxation,
        bool self_Employed_Business_Taxes,
        bool gST_PST_WCB_Returns,
        bool tax_Returns,
        bool payroll_Services,
        bool previous_Year_Filings,
        bool government_Requisite_Form_Applications,
        string other)
    {
        this.Bookkeeping = bookkeeping;
        this.Personal_Income_Taxation = personal_Income_Taxation;
        this.Self_Employed_Business_Taxes = self_Employed_Business_Taxes;
        this.GST_PST_WCB_Returns= gST_PST_WCB_Returns;
        this.Tax_Returns = tax_Returns;
        this.Payroll_Services = payroll_Services;
        this.Previous_Year_Filings = previous_Year_Filings;
        this.Government_Requisite_Form_Applications = government_Requisite_Form_Applications;
        this.Other = other;

    }

    public override bool IsValid(object value)
    {
        return base.IsValid(value);
    }
}

有没有其他方法可以解决这个问题? (最好使用自定义属性)。 第一次发问题,如有遗漏请见谅。 谢谢

编辑

在解决方案的帮助下,我能够使复选框错误来自服务器端,但我仍然有一个问题,即当我按下提交按钮时,复选框错误不会与其他两个同时出现。 通过遵循教程,我能够通过在我的视图中包含这段代码来从客户端显示其他两个错误,该代码伴随着 asp.net 核心项目的创建

 @section Scripts { <partial name="_ValidationScriptsPartial" /> }

_ValidationScriptsPartial.cshtml

 <environment include="Development"> <script src="~/Identity/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> </environment> <environment exclude="Development"> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js" asp-fallback-src="~/Identity/lib/jquery-validation/dist/jquery.validate.min.js" asp-fallback-test="window.jQuery && window.jQuery.validator" crossorigin="anonymous" integrity="SOME INFO"> </script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js" asp-fallback-src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive" crossorigin="anonymous" integrity="SOME INFO"> </script> </environment>

一些参考是here

  1. 文章custom-data-annotation-validation-in-mvc
  2. CompareAttribute.csComparePropertyAttribute.cs的源代码
  3. 3rd-party ExpressiveAnnotations

因此,以类似的方式,自定义ValidationAttribute可以使用反射通过其属性名称( the name from declaration or argument )来获取运行时值,以查看该属性是否具有所需的值或格式。

public class CheckboxAndOtherValidation : ValidationAttribute
{
    readonly object TRUE = true;
    string[] _alltheOtherProperty;

    public CheckboxAndOtherValidation(params string[] alltheOthersProperty)
    {
        _alltheOtherProperty = alltheOthersProperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (_alltheOtherProperty?.Count() > 0 != true)
        {
            return ValidationResult.Success;
        }

        var otherPropertyInfo = validationContext.ObjectType.GetProperty(nameof(Client.Other));
        if (otherPropertyInfo != null)
        {
            object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
            if (otherPropertyValue != null && !string.IsNullOrEmpty(otherPropertyValue.ToString()))
            {
                return ValidationResult.Success;
            }
        }

        for (var i = 0; i < _alltheOtherProperty.Length; ++i)
        {
            var prop = _alltheOtherProperty[i];
            var propertyInfo = validationContext.ObjectType.GetProperty(prop);
            if (propertyInfo == null)
            {
                continue;
            }

            object propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
            if (Equals(TRUE, propertyValue))
            {
                return ValidationResult.Success;
            }
        }

        return new ValidationResult("Must exist at least one field is true", _alltheOtherProperty);
    }
}

因为我选择传递属性名称数组列表作为参数,现在 class客户端可以有这样一个简化和更清晰的用法,

public class Client
{
    [CheckboxAndOtherValidation(nameof(Bookkeeping),
        nameof(Personal_Income_Taxation),
        nameof(Self_Employed_Business_Taxes),
        nameof(GST_PST_WCB_Returns),
        nameof(Tax_Returns),
        nameof(Payroll_Services),
        nameof(Previous_Year_Filings),
        nameof(Government_Requisite_Form_Applications))]
    public bool AreCheckboxesAndOtherValid { get; set; }
}    

暂无
暂无

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

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