概述
silky 框架内置了参数验证机制,在 RPC 通信过程中会自动对服务条目的输入参数进行验证。验证支持以下两种方式:
| 验证方式 | NuGet 包 | 说明 |
|---|---|---|
| DataAnnotations(数据注解) | Silky.Core(已内置) | 使用 .NET 标准的 System.ComponentModel.DataAnnotations 特性 |
| FluentValidation | Silky.Validation.Fluent | 使用 FluentValidation 进行复杂验证规则定义 |
验证失败时,框架会抛出验证异常(ValidationException),HTTP 响应状态码为 400 Bad Request。
使用 DataAnnotations 进行验证
这是最简单的方式,直接在 DTO 类的属性上标注验证特性:
public class CreateOrderInput
{
[Required(ErrorMessage = "商品ID不能为空")]
public long ProductId { get; set; }
[Range(1, 9999, ErrorMessage = "购买数量必须在 1-9999 之间")]
public int Quantity { get; set; }
[Required(ErrorMessage = "收货地址不能为空")]
[MaxLength(200, ErrorMessage = "收货地址不能超过 200 个字符")]
public string Address { get; set; }
[Phone(ErrorMessage = "手机号码格式不正确")]
public string Phone { get; set; }
}
在服务接口方法中使用该 DTO:
[ServiceRoute]
public interface IOrderAppService
{
Task<OrderOutput> CreateOrderAsync(CreateOrderInput input);
}
框架会在 RPC 调用前自动触发验证,无需在实现代码中手动调用 Validate()。
使用 FluentValidation 进行验证
对于复杂的验证规则,推荐使用 FluentValidation,它提供了更强大、更灵活的验证 DSL。
安装包
PM> Install-Package Silky.Validation.Fluent -Version 3.9.1
定义验证器
继承 AbstractValidator<T> 定义验证规则,并实现 IScopedDependency(框架会自动注册):
using FluentValidation;
using Silky.Core.DependencyInjection;
public class CreateOrderInputValidator : AbstractValidator<CreateOrderInput>, IScopedDependency
{
public CreateOrderInputValidator()
{
RuleFor(x => x.ProductId)
.GreaterThan(0).WithMessage("商品ID必须大于0");
RuleFor(x => x.Quantity)
.InclusiveBetween(1, 9999).WithMessage("购买数量必须在 1-9999 之间");
RuleFor(x => x.Address)
.NotEmpty().WithMessage("收货地址不能为空")
.MaximumLength(200).WithMessage("收货地址不能超过 200 个字符");
RuleFor(x => x.Phone)
.NotEmpty().WithMessage("手机号码不能为空")
.Matches(@"^1[3-9]\d{9}$").WithMessage("手机号码格式不正确");
}
}
验证器定义完成后,框架会自动识别并在 RPC 调用前执行验证,无需额外配置。
异步验证
FluentValidation 支持异步验证规则(如需查询数据库校验唯一性):
public class CreateAccountInputValidator : AbstractValidator<CreateAccountInput>, IScopedDependency
{
private readonly IAccountRepository _accountRepository;
public CreateAccountInputValidator(IAccountRepository accountRepository)
{
_accountRepository = accountRepository;
RuleFor(x => x.UserName)
.NotEmpty().WithMessage("用户名不能为空")
.MustAsync(async (userName, cancellationToken) =>
{
return !await _accountRepository.ExistsAsync(a => a.UserName == userName);
}).WithMessage("用户名已存在");
}
}
禁用验证
在方法级别禁用
对特定服务方法禁用验证,使用 [DisableValidation] 特性:
[ServiceRoute]
public interface IOrderAppService
{
Task<OrderOutput> CreateOrderAsync(CreateOrderInput input);
// 该方法不进行参数验证
[DisableValidation]
Task<string> InternalSyncAsync(SyncInput input);
}
在类级别禁用
对整个服务类的所有方法禁用验证:
[DisableValidation]
public class InternalSyncAppService : IInternalSyncAppService
{
// 所有方法均不进行参数验证
}
验证配置
参数验证默认是开启的。如需全局关闭自动参数验证,可以在构建主机时通过 SilkyApplicationCreationOptions 设置:
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureSilkyGeneralHostDefaults(options =>
{
options.AutoValidationParameters = false; // 关闭自动参数验证(默认 true)
});
说明
AutoValidationParameters 默认值为 true,表示对所有服务条目开启参数验证。如果需要对单个方法或整个类禁用验证,推荐使用 [DisableValidation] 特性,而不是全局关闭。
此外,[EnableValidationAttribute] 可用于在类级别 [DisableValidation] 时,对特定方法重新启用验证。
