C# ASP.NET Core 在 Service 中驗證 ValidationAttribute 屬性

在 ASP.NET Core 中可以在模型中加上繼承 ValidationAttribute 的驗證屬性:
    
using System.ComponentModel.DataAnnotations;


public class UserDto
{
    [Required] 
    public int? Id { get; set; }

    [Required]
    [StringLength(10, MinimumLength = 3)]
    public string? Name { get; set; }
}
    

在 ASP.NET Core 中的 Controller 只要繼承 ControllerBase 就會自動驗證, 在 ASP.NET Core MVC 中可以在 Controller 內使用下面的程式碼驗證模型屬性是否正確:
    
    if (!ModelState.IsValid)
    {
        return View(userDto);
    }
    

也可以使用下面的程式碼重新執行驗證
    
    ModelState.ClearValidationState(nameof(UserDto));
    if (!TryValidateModel(userDto, nameof(UserDto)))
    {
        return Page();
    }
    

不過上面的程式碼都有一個小小的問題,就是只能在繼承了 ControllerBase 或是 Controller 的 Controller 下執行,不然會找不到 ModelState 和 TryValidateModel。

如果要在 Service 層中驗證,除了將 ModelState 帶入 Service 層中以外,還有沒有其他更好的方法呢?有的,而且非常簡單:
    
public class UserService
{
    public void Get(UserDto dto)
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new ValidationContext(dto);
        Validator.TryValidateObject(dto, validationContext, validationResults, true);

        if (validationResults.Count <= 0) return; // 沒有錯誤就跳出

        Dictionary<string, string> errors = new();
        foreach (var validationResult in validationResults)
        {
            foreach (var memberName in validationResult.MemberNames)
            {
                errors.Add(memberName, validationResult.ErrorMessage!);
            }
        }

        // 列出所有驗證失敗的欄位和原因
        foreach (var pair in errors)
        {
            Console.WriteLine($"{pair.Key}: {pair.Value}");
        }
    }
}
    



參考資料:
Microsoft.Learn - Model validation in ASP.NET Core MVC and Razor Pages

留言