使用 Fluent Validation 验证可以为 null 的枚举值

Validate Nullable Enum Values using Fluent Validation

提问人:user007 提问时间:10/19/2023 最后编辑:user007 更新时间:10/19/2023 访问量:41

问:

我有一个可为 null 的枚举列表,我只想在列表不为 null 时验证枚举。我确实看到了验证&的选项。但只想在employeeTypes .我怎样才能做到这一点?NullIsInEnumIS NOT NULL

public enum EmployeeType
{
    LEVEL_1 = 1,
    LEVEL_2 = 2,
    LEVEL_3 = 3,
    LEVEL_4 = 4
}

public async Task<IActionResult> GetEmployeesAsync(List<EmployeeType>? employeeTypes)
{
   //TODO: I want to move this to Fluent Validation
   if (employeeTypes!= null && employeeTypes.Any(x => !Enum.IsDefined(x)))
   {
    return BadRequest("employeeTypes parameter is Invalid");
   }
   
   //Return employees based on employeeTypes if not null, else return all employees
   var employees = await _engine.GetEmployes(employeeTypes);
   return Ok(employees);
}


net-6.0 Fluent验证 C#-7.0

评论

0赞 Luuk 10/19/2023
枚举类型 E 的默认值是表达式 (E)0 生成的值,即使零没有相应的枚举成员也是如此。
0赞 user007 10/19/2023
@Luuk:我不明白你的意思。我所要做的就是将其移动到 FluentValidation。如果您需要更多详细信息,请告诉我。if condition on the enumeration
0赞 Luuk 10/19/2023
employeeTypes的类型为 ,即 .它永远不会有值,因为它默认为 。EmployeeTypeenumnull0
0赞 Prolog 10/19/2023
List<EmployeeType>?与 不同。阅读有关可为 null 类型的详细信息:learn.microsoft.com/en-us/dotnet/csharp/nullable-referencesList<EmployeeType?>
0赞 user007 10/19/2023
@Prolog:这正是我想要的。如果 employeeTypes 为 null,我想返回所有员工。但是,如果它不为 null,那么我想返回属于该过滤器的所有员工。我要问的是如何转换为流畅的验证?我只想在employeeTypes不为null时验证Enum.IsDefinedif (employeeTypes != null && employeeTypes.Any(x => !Enum.IsDefined(x)))

答:

0赞 user007 10/19/2023 #1

我为枚举添加了自定义验证,并暂时解决了这个问题。如果有更好的解决方案,请告诉我。

private static bool IsValidEmployeeTypes(List<LeadType>? employeeTypes)
{
    if (employeeTypes == null || employeeTypes.Count == 0)
    {
        return true;
    }

    return employeeTypes.All(Enum.IsDefined);
}

然后从 Validator 函数调用上述方法,如下所示:

RuleFor(x => x.employeeTypes)
    .Must(IsValidEmployeeTypes)
    .WithMessage("Invalid value for employeeTypes");

0赞 Luuk 10/19/2023 #2

请看一下:

  static void Main() {
    Console.WriteLine("Hello World");
    
    EmployeeType a = new EmployeeType();
    EmployeeType? b = new EmployeeType();
    
    Console.WriteLine("a:{0} b:{1}", a, b);
    a = EmployeeType.LEVEL_2;
    b = EmployeeType.LEVEL_3;
    Console.WriteLine("a:{0} b:{1}", a, b);
    
    a = (EmployeeType)6;
    b = (EmployeeType)7;
    Console.WriteLine("a:{0} b:{1}", a, b);
    
    foreach(var item in System.Enum.GetValues(typeof(EmployeeType))) {
        Console.Write("{0}, ", item);
    }
    Console.WriteLine();
  }
  
  public enum EmployeeType
{
    LEVEL_1 = 1,
    LEVEL_2 = 2,
    LEVEL_3 = 3,
    LEVEL_4 = 4
}

输出:

Hello World
a:0 b:0
a:LEVEL_2 b:LEVEL_3
a:6 b:7
LEVEL_1, LEVEL_2, LEVEL_3, LEVEL_4, 

请参见:https://onlinegdb.com/saNCB96Nmq

可以使用 List 扩展此示例,请参阅: https://onlinegdb.com/zJN7LrnhX

评论

0赞 user007 10/19/2023
它不是我设置为 null 的枚举。它是 .我猜你没有注意到......List<enum>?