【问题标题】:How to create a custom validation attribute with parameters consisting of model properties如何使用由模型属性组成的参数创建自定义验证属性
【发布时间】:2020-05-10 02:01:21
【问题描述】:

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

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

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

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

我为自定义验证属性创建的实用程序类 - 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>

【问题讨论】:

    标签: javascript c# html jquery asp.net-core


    【解决方案1】:

    这里有一些参考资料

    1. 文章custom-data-annotation-validation-in-mvc
    2. CompareAttribute.csComparePropertyAttribute.cs的源代码
    3. 第三方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);
        }
    }
    

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

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

    【讨论】:

    • 如果我错了,请纠正我,但在第一个 if 语句中,您正在检查 _alltheOtherProperty 是否有超过 0 个值,第二个 if 语句您正在检查“Other”字段是否不为空,最后的for循环检查它们是否都不为假?
    • @gupta_28 我认为您已经很好地阅读了我的示例。随意修改以满足您的需求。例如,如果_alltheOtherProperty 是 NullOrEmpty 数组,您可以返回错误。
    • 还有,什么是“ClientAddressInfo”?
    • @gupta_28 抱歉打错了。我已替换为您的类 Client。请再次检查。
    • 好吧,我是这么认为的。所以我尝试使用你的解决方案,我得到的是当我点击提交按钮时,我仍然没有得到我正在寻找的复选框错误。我尝试将“ErrorMessage = 'blah'”作为属性的一部分添加到我的客户端类中,但它仍然无法正常工作。我在 IsValid 方法中放置了一个调试器,但只有当我输入有效的姓名和联系电话时它才会被命中。有没有办法将消息与我显示的其他两条错误消息一起获取?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多