使用数据注释在 c# 中进行数据验证

Posted

技术标签:

【中文标题】使用数据注释在 c# 中进行数据验证【英文标题】:Data Validation in c# using Data Annotations 【发布时间】:2021-01-16 15:10:14 【问题描述】:

我正在将客户端的数据迁移到需要验证所有属性的新数据库 (SQL SERVER)。 我尝试添加数据注释,但没有按预期工作。

这是我的示例代码:

 public class SellerDetailModel
    
        [Required, RegularExpression("[0-9]2[0-9A-Z]13")]
        public string GSTNumber; 

        [Required, StringLength(100, MinimumLength = 3)]
        public string LegalName;

        [StringLength(100, MinimumLength = 3)]
        public string TradingName;

        [Required, StringLength(100, MinimumLength = 3)]
        public string Address1;

        [StringLength(100, MinimumLength = 3)]
        public string Address2;

        [Required, StringLength(50, MinimumLength = 3)]
        public string Location;

        [Required, StringLength(6)]
        public int PinCode;

        [Required, StringLength(2, MinimumLength = 1)]
        public string StateCode;

        [StringLength(12, MinimumLength = 6)]
        public string ContactNumber;

        [Required, StringLength(100, MinimumLength = 6)]
        public string EmailId;
    

现在,在另一个类(业务逻辑)中,我正在为这个类分配值。

//"invoice" is an object having seller related data

SellerDetailModel dataTransferObject = new SellerDetailModel
                    
                        GSTNumber = invoice.SellerGSTNumber,
                        LegalName = invoice.SellerLegalName,
                        TradingName = invoice.SellerTradingName,
                        Address1 = invoice.SellerAddress1,
                        Address2 = invoice.SellerAddress2,
                        Location = invoice.SellerLocation,
                        PinCode = Convert.ToInt32(invoice.SellerPinCode),
                        StateCode = invoice.SellerStateCode,
                        ContactNumber = invoice.SellerContactNumber,
                        EmailId = invoice.SellerEmailId,
                    ;

   

但即使在添加了所需的属性、Regex、String Length 等之后......它根本没有被验证, 它仍然接受所有的空值。 有人可以帮我如何验证这些属性吗?

如果迁移过程中出现错误,我只想创建一个日志数据。

编辑

我已经尝试过下面的方法,但还是不行……

public string Validate()
        
            ValidationContext context = new ValidationContext(this);
            List<ValidationResult> results = new List<ValidationResult>();
            bool isValid = Validator.TryValidateObject(this, context, results, true);

            if (!isValid)
            
                StringBuilder sbrErrors = new StringBuilder();
                foreach (var validationResult in results)
                
                    sbrErrors.AppendLine(validationResult.ErrorMessage);
                
                return sbrErrors.ToString();
            
            else
                return string.Empty;
        


 var validation = dataTransferObject.Validate() //always gives string.Empty

【问题讨论】:

属性不验证任何东西。他们告诉验证者如何验证。你有一个验证器吗?而且,验证模型属性的任务与您使用的数据库几乎无关。 @GSerg 你能解释一下如何添加验证器吗? (我是 C# 新手) 这能回答你的问题吗? How to manually validate a model with attributes? 我试过了,但还是不行, 【参考方案1】:

问题在于 ValidationContext 适用于属性而不是字段。

我通过反编译 ValidationContext 类发现它只会搜索属性找到了答案。

您需要将您的代码更改为此才能使其工作,其中字段已转换为属性。

public class SellerDetailModel

    [Required, RegularExpression("[0-9]2[0-9A-Z]13")]
    public string GSTNumber  get; set; 

    [Required, StringLength(100, MinimumLength = 3)]
    public string LegalName  get; set; 

    [StringLength(100, MinimumLength = 3)] 
    public string TradingName  get; set; 

    [Required, StringLength(100, MinimumLength = 3)]
    public string Address1  get; set; 

    [StringLength(100, MinimumLength = 3)]
    public string Address2  get; set; 

    [Required, StringLength(50, MinimumLength = 3)]
    public string Location  get; set; 

    [Required, StringLength(6)]
    public string PinCode  get; set; 

    [Required, StringLength(2, MinimumLength = 1)]
    public string StateCode  get; set; 

    [StringLength(12, MinimumLength = 6)]
    public string ContactNumber  get; set; 

    [Required, StringLength(100, MinimumLength = 6)]
    public string EmailId  get; set; 

    public string Validate()
    
        ValidationContext context = new ValidationContext(this);
        List<ValidationResult> results = new List<ValidationResult>();
        bool isValid = Validator.TryValidateObject(this, context, results, true);

        if (!isValid)
        
            StringBuilder sbrErrors = new StringBuilder();
            foreach (ValidationResult validationResult in results)
            
                sbrErrors.AppendLine(validationResult.ErrorMessage);
            
            return sbrErrors.ToString();
        
        else
            return string.Empty;
    

看起来您不需要在 Invoice.PinCode 字段上转换为 int,否则 Validation 函数会因为它正在寻找字符串而崩溃。

public class Invoice

    public string SellerGSTNumber  get; set; 
    public string SellerLegalName  get; set; 
    public string SellerTradingName  get; set; 
    public string SellerAddress1  get; set; 
    public string SellerAddress2  get; set; 
    public string SellerLocation  get; set; 
    public string SellerPinCode  get; set; 
    public string SellerStateCode  get; set; 
    public string SellerContactNumber  get; set; 
    public string SellerEmailId  get; set; 


public class Mapper

    public static SellerDetailModel Map(Invoice invoice)
    
        SellerDetailModel dataTransferObject = new SellerDetailModel
        
            GSTNumber = invoice.SellerGSTNumber,
            LegalName = invoice.SellerLegalName,
            TradingName = invoice.SellerTradingName,
            Address1 = invoice.SellerAddress1,
            Address2 = invoice.SellerAddress2,
            Location = invoice.SellerLocation,
            PinCode = invoice.SellerPinCode,
            StateCode = invoice.SellerStateCode,
            ContactNumber = invoice.SellerContactNumber,
            EmailId = invoice.SellerEmailId,
        ;

        return dataTransferObject;
    

【讨论】:

以上是关于使用数据注释在 c# 中进行数据验证的主要内容,如果未能解决你的问题,请参考以下文章

使用数据注释进行模型验证的错误消息

使用 rsa 在 c# 中验证来自节点的签名数据

数据注释/验证和动态值

在 C# 中针对 XSD 模式验证 json 数据

FluentValidation在C#中是怎么进行数据验证的

使用数据注释的依赖属性的自定义模型验证