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