oluwaremieo
oluwaremieo

Reputation: 61

System.ComponentModel.DataAnnotations validation attributes not working as expected

I have checked for possible solutions to this and haven't been able to get any meaningful solution. I am working on an ASP.NET Web API project and I have a controller route with the below method signature:

[HttpPost("cimgAirtimeVending/{msisdn}")]
public async Task<ActionResult<ResponseObject>> CIMGAirtimeVending([FromBody] CIMGBillPaymentRequest _cimgAirtimeBillPaymentRequest, [Required, RegularExpression(@"\d{13}")] string msisdn)

CIMGBillPaymentRequest is a DTO with validations defined on each property as follows:

public class CIMGBillPaymentRequest
{
    [Required, RegularExpression(@"\w+"), StringLength(30)]
    public string RequestId { get; set; }
    
    [Required, StringLength(10, MinimumLength = 10), RegularExpression(@"\d+")]
    public string DebitAccount { get; set; }
    
    /* [Required, RegularExpression(@"\w+")]
    public string Narration { get; set; } */
    
    [Required]
    public bool IsFees { get; set; }
    
    public List<Charge> Charges { get; set; }
    
    [Required, RegularExpression(@"[\w-]+")]
    public string ProductId { get; set; }
    
    [Required, Range(1, 100, ErrorMessage = "Enter valid ChannelId")]
    public int ChannelId { get; set; }
    
    // [Required, Range(100, 100000, ErrorMessage = "Enter valid Amount (>=100)")]
    public decimal Amount { get; set; }
    
    [Required, RegularExpression(@"\w+")]
    public string CustomerReference { get; set; }
}
public class Charge
{
    // [StringLength(10, MinimumLength = 10), RegularExpression(@"\d{10,}")]
    [RegularExpression(@"\w+")]
    public string Account { get; set; }
        
    public decimal Fee { get; set; }
}

The strange thing is, it appears not all the validation works. If isFees is removed from the DTO, it should return a Required validation error, but that does not happen. The validation is completely ignored. This does not happen with the ProductId property. A Required validation error is returned if it is not included in the DTO

Another issue I had was with the Account property in the Charge class. If you look at the line commented above it, you will see I am using a Regex validation RegularExpression(@"\d{10,}")] i.e. to ensure that it is a string of at least 10 digits. However, this validation is completely ignored and I had to use [RegularExpression(@"\w+")].

Any idea what the issue is and possible solution?

Upvotes: 1

Views: 2392

Answers (1)

Ids van der Zee
Ids van der Zee

Reputation: 882

Take a look at the documentation here.

"The RequiredAttribute attribute specifies that when a field on a form is validated, the field must contain a value. A validation exception is raised if the property is null, contains an empty string (""), or contains only white-space characters."

"If the MVC data model or entity partial class contains a field that is annotated with the RequiredAttribute attribute, but the page does not contain the property, an error is not raised. Validation occurs only for fields that are submitted to the server."

If you leave out the property entirely then the required validation will not trigger. It will only trigger when explicitly called with null, empty string or string with only whitespace. Therefore I'm assuming the required check on some other fields namely the struct fields also don't work, however when you then check for a range, like with the ChannelId property it will validate the range. The issue here is that a struct can never be null. This means the RequiredAttribute won't work on bool, int, decimal, etc. fields.

In this case when not providing anything for IsFees will set the property with the value default(bool) the default value for a bool is false.

As for the Account field, look at the documentation here

"You apply the RegularExpressionAttribute attribute to a property when you need to validate values for the property against a regular expression. The regular expression enables you to specify very precisely the format of valid values. The Pattern property contains the regular expression. If the value of the property is null or an empty string (""), the value automatically passes validation for the RegularExpressionAttribute attribute. To validate that the value is not null or an empty string, use the RequiredAttribute attribute."

When providing null, or an empty string to a field with RegularExpressionAttribute it will pass the check. This means, for your Account field you need to use [Required, RegularExpression(@"\d{10,}")].

Upvotes: 3

Related Questions