我目前正在一个 C# 项目中工作,并使用 FluentValidator 进行一些验证。
我对在 PUT 请求中进行验证有疑问。
这是我从请求中收到的对象
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Contatc { get; set; }
}
有一条规则,2 个不同的用户不能拥有相同的电子邮件。
这是它的实现:
RuleFor(r => r)
.NotEmpty()
.WithErrorMessage("Object is Null")
.MustAsync(async (x, _) =>
{
var emailValidator = await userRepository.CheckIfEmailIsDuplicate(x.Email);
return !emailValidator ;
})
.WithErrorMessage("Email already Existis");
“CheckIfEmailIsDuplicate”的实现:
private static readonly string QUERY_CHECK_IF_EMAIL_IS_DUPLICATE = "SELECT COUNT(*) " +
"FROM User" +
@"WHERE Email = @email";
public async Task<bool> CheckIfEmailIsDuplicate(string email)
{
using var connection = dbConnectionFactory.Invoke(DbConnections.DEFAULT_CONNECTION);
var validator = await connection.QueryAsync<int>(
sql: QUERY_CHECK_IF_EMAIL_IS_DUPLICATES ,
param: new
{
email
});
return Convert.ToBoolean(validator.FirstOrDefault());
}
我想知道是否有一种方法可以仅验证我在请求中更改的属性。例如,假设有 3 个用户:
{ 1, "User 1", "[email protected]", "1234567890" };
{ 2, "User 2", "[email protected]", "9876543210" };
{ 3, "User 3", "[email protected]", "5555555555" };
我只想更改 1 号的“名称”,“用户 1”->“Jonh”。 当我这样做时,它给我一个错误,“电子邮件已经存在”
有没有一种方法可以将原始用户与更新用户进行比较并仅验证更改的属性?
我还有这个功能可以在我的存储库中通过 ID 获取用户:
private static readonly string QUERY_GET_EMAIL_BY_ID = @"SELECT * FROM User WHERE Id = @id";
public async Task<Product> GetEmailByIdAsync(Guid id)
{
using var connection = dbConnectionFactory.Invoke(DbConnections.DEFAULT_CONNECTION);
var product = await connection.QueryAsync<Product>(sql: QUERY_GET_EMAIL_BY_ID, param: new { id });
return product.FirstOrDefault();
}
我不知道是否可以在验证类中使用此函数,当我颤抖时,我无法弄清楚如何将请求 Id 作为参数传递。
谢谢大家!
要使用 FluentValidation 仅验证 PUT 请求中已更改的属性,您可以将原始用户对象与更新的用户对象进行比较,并从验证中排除未更改的属性。
以下是如何实现此目标的示例:
public class UserValidator : AbstractValidator<User>
{
private readonly IUserRepository userRepository;
public UserValidator(IUserRepository userRepository)
{
this.userRepository = userRepository;
RuleFor(r => r)
.NotEmpty()
.WithErrorMessage("Object is Null")
.MustAsync(async (user, cancellation) =>
{
var originalUser = await userRepository.GetUserById(user.Id);
if (originalUser == null)
{
return false; // Assuming the user with the given Id doesn't exist
}
return await IsEmailUnique(user, originalUser);
})
.WithErrorMessage("Email already exists");
}
private async Task<bool> IsEmailUnique(User user, User originalUser)
{
if (user.Email != originalUser.Email)
{
// Email has changed, check for uniqueness
var isDuplicate = await userRepository.CheckIfEmailIsDuplicate(user.Email);
return !isDuplicate;
}
return true; // Email hasn't changed
}
}
在上面的示例中,
UserValidator
类在其构造函数中采用IUserRepository
依赖项来执行必要的数据库操作。
IsEmailUnique
方法将更新用户的电子邮件属性与原始用户进行比较。如果电子邮件已更改,它将使用存储库中的 CheckIfEmailIsDuplicate
方法执行重复电子邮件检查。如果电子邮件未更改,则认为其有效。
通过使用此方法,您可以仅验证 PUT 请求中已更改的属性,并排除未修改的属性。
注意:确保您已在
GetUserById
中实现了 IUserRepository
方法,以通过其 Id 检索原始用户。
关于将请求 Id 作为参数传递给验证类的问题,您可以通过
UserValidator
类的构造函数传递它,或者将其设置为 User
类本身的属性。然后,您可以在 MustAsync
方法中访问它以执行必要的验证。