问题描述
我用一个打字稿项目构建了nestjs,我正在尝试验证过滤器查询参数。 我只希望过滤键和值可以通过验证。 好的参数示例:通过验证
public List<GrantedAuthority> getAuthorities(String token) {
String[] claims = getClaimsFromToken(token);
return StreamSupport.stream(claims).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
错误参数示例:验证失败
any-endpoint?filters={"userIds"=["1","2","5"],"ages"=[25]}
any-endpoint?filters={"names"=["david","samuel"],"ages"=[21]}
我的代码
any-endpoint?filters={"blaBla"=["1","ages"=[25]} // here the key blaBla not one of the filters options
any-endpoint?filters={"names"=[1,2]} // here the values of names is not string,it should be string
怎么做?
解决方法
好的,因此,如果您真的想以该格式发送查询,则可以使用@Transform()
中的class-transformer
装饰器,并使用plainToClass
来转换过滤器值。为此,您需要做一些事情。
-
@ValidateNested()
装饰器对于确保可以按预期进行验证是必需的。也就是说,可以验证子对象。 -
将需要使用
@Transform()
装饰器。这对我有用
import { IsOptional,ValidateNested } from 'class-validator';
import { Transform,plainToClass } from 'class-transformer'
import { FiltersOptionsDto } from './filter.dto';
export class AQueryDto {
@IsOptional()
@ValidateNested()
@Transform((value) => plainToClass(FiltersOptionsDto,JSON.parse(value.replace(/=/g,':'))))
filters?: FiltersOptionsDto;
}
每个=
都必须设为:
,以便它是正确的JSON格式(我也将类分开,因为我更喜欢每个文件一个类)。使用上面的方法,传递给filters
的值将从字符串值获取到JSON(纯文本),然后从纯文本获取到类。
- 您需要在
forbidNonWhitelisted: true
中设置ValidationPipe
。我这样做是这样的:
@Module({
providers: [
{
provide: APP_PIPE,useValue: new ValidationPipe({ forbidNonWhitelisted: true })
}
]
})
export class AppModule {}
(当然还有其他提供者和控制者)。我还喜欢添加transform: true
,以便它不再是JSON或字符串,而是一个实际的类。
现在您可以传递
?filters={"userIds"=["1","2","5"],"ages"=["25"]}
它会在尝试传递时成功
?filters={"blaBla"=["1","ages"=[25]}
它将失败。
,还没有测试过,但是从docs看来,这就是您所需要的:
export class AQueryDto {
@IsOptional()
@ValidateNested() // +
filters?: FiltersOptionsDto;
}