Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การ Validate DateOfBirth ไม่ให้เกินปีปัจจุบันด้วย FluentValidation ใน C#

การ Validate วันที่เกิด (DateOfBirth) ให้ไม่อยู่ในอนาคต และไม่อายุเกินไป (เช่น > 120 ปี) ด้วย FluentValidation

หลักการ Validate

  • Year ≤ Current Year (ไม่ใช่ปีหน้า)
  • Year > Current Year - 120 (ไม่อายุเกิน 120 ปี)
  • อาจเพิ่ม: ต้องมีอายุ ≥ 18 ปี (Business Rule)

ตัวอย่างโค้ดเต็ม

using FluentValidation;
using FluentValidation.Results;
using System;
using System.Collections.Generic;

public class PersonModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public decimal AccountBalance { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class PersonValidator : AbstractValidator<PersonModel>
{
    public PersonValidator()
    {
        RuleFor(p => p.DateOfBirth)
            .Must(BeAValidDateOfBirth)
            .WithMessage("'{PropertyName}' ไม่ถูกต้อง: ต้องไม่เป็นปีหน้า และอายุไม่เกิน 120 ปี");
            
        // หรือเขียน Inline ได้
        RuleFor(p => p.DateOfBirth)
            .LessThanOrEqualTo(DateTime.Today)
            .WithMessage("'{PropertyName}' ต้องไม่เป็นวันในอนาคต")
            .GreaterThanOrEqualTo(DateTime.Today.AddYears(-120))
            .WithMessage("'{PropertyName}' อายุต้องไม่เกิน 120 ปี");
    }
    
    // Custom Validation Method
    private bool BeAValidDateOfBirth(DateTime date)
    {
        int currentYear = DateTime.Today.Year;
        int dobYear = date.Year;
        
        // ต้องไม่เกินปีปัจจุบัน และไม่น้อยกว่า 120 ปีที่แล้ว
        return dobYear <= currentYear && dobYear > (currentYear - 120);
    }
}

static void Main()
{
    var person = new PersonModel
    {
        FirstName = "TestUser",
        LastName = "TestUser",
        AccountBalance = 100,
        DateOfBirth = DateTime.Today.AddYears(1) // ปีหน้า - Invalid!
    };
    
    var validator = new PersonValidator();
    ValidationResult result = validator.Validate(person);
    
    if (!result.IsValid)
    {
        foreach (var failure in result.Errors)
        {
            Console.WriteLine($"[{failure.PropertyName}] {failure.ErrorMessage}");
        }
    }
    else
    {
        Console.WriteLine("Validation Passed!");
    }
}

ผลลัพธ์

[DateOfBirth] 'DateOfBirth' ไม่ถูกต้อง: ต้องไม่เป็นปีหน้า และอายุไม่เกิน 120 ปี
[DateOfBirth] 'DateOfBirth' ต้องไม่เป็นวันในอนาคต

วิธีอื่นๆ ที่มีประโยชน์

1. ตรวจสอบอายุขั้นต่ำ (เช่น ≥ 18 ปี)

RuleFor(p => p.DateOfBirth)
    .Must(dob => dob <= DateTime.Today.AddYears(-18))
    .WithMessage("ต้องมีอายุอย่างน้อย 18 ปี");

2. ใช้ LessThanOrEqualTo / GreaterThanOrEqualTo (Built-in)

RuleFor(p => p.DateOfBirth)
    .LessThanOrEqualTo(DateTime.Today)                    // ไม่เกินวันนี้
    .GreaterThanOrEqualTo(DateTime.Today.AddYears(-120)); // ไม่น้อยกว่า 120 ปีก่อน

3. Custom Validator แบบ Reusable

public class DateOfBirthValidator : PropertyValidator<DateTime>
{
    private readonly int _minAge;
    private readonly int _maxAge;
    
    public DateOfBirthValidator(int minAge = 0, int maxAge = 120)
    {
        _minAge = minAge;
        _maxAge = maxAge;
    }
    
    public override bool IsValid(ValidationContext<DateTime> context, DateTime value)
    {
        var today = DateTime.Today;
        var minDate = today.AddYears(-_maxAge);
        var maxDate = today.AddYears(-_minAge);
        
        return value >= minDate && value <= maxDate;
    }
    
    protected override string GetDefaultMessageTemplate(string errorCode)
        => "วันที่เกิดต้องอยู่ระหว่าง {MinAge} ถึง {MaxAge} ปี";
}

// ใช้งาน
RuleFor(p => p.DateOfBirth).SetValidator(new DateOfBirthValidator(18, 120));

ข้อควรระวัง

  • ใช้ DateTime.Today (Date Only) ไม่ใช่ DateTime.Now (มี Time Component)
  • Time Zone: พิจารณาใช้ DateTimeOffset หรือ UTC หากระบบ Multi-timezone
  • Leap Year: 29 Feb จัดการได้อัตโนมัติโดย DateTime