自定义验证器验证对象键
custom-validator validate object keys
我用打字稿项目构建了 nestjs,我正在尝试验证过滤器查询参数。
我只希望过滤键和值可以通过验证。
良好参数的示例:通过验证
any-endpoint?filters={"userIds"=["1","2","5"],"ages"=[25]}
any-endpoint?filters={"names"=["david","samuel"],"ages"=[21]}
错误参数示例:验证失败
any-endpoint?filters={"blaBla"=["1","2","5"],"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
我的代码
import { IsNumber, IsOptional,IsArray, IsString } from 'class-validator';
class FiltersOptionsDto {
@IsOptional()
@IsArray()
@IsString({ each: true })
userIds?: string[];
@IsOptional()
@IsArray()
@IsString({ each: true })
ages?: number[];
@IsOptional()
@IsArray()
@IsNumber({}, { each: true })
names?: string[];
}
export class AQueryDto {
@IsOptional()
// what to add here?
filters?: FiltersOptionsDto;
}
怎么做?
还没有测试过,但是从 docs 我认为这就是你需要的:
export class AQueryDto {
@IsOptional()
@ValidateNested() // +
filters?: FiltersOptionsDto;
}
好吧,所以如果你真的想以那种格式发送查询,你可以使用 class-transformer
中的 @Transform()
装饰器并使用 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 格式(我也分开了 classes 因为我更喜欢一个class 每个文件)。通过以上,传入 filters
的值将从字符串值获取到 JSON(普通),然后从普通到 class.
- 您需要在
ValidationPipe
中设置 forbidNonWhitelisted: true
。我是这样做的:
@Module({
providers: [
{
provide: APP_PIPE,
useValue: new ValidationPipe({ forbidNonWhitelisted: true })
}
]
})
export class AppModule {}
(当然还有其他提供者和控制者)。我还想添加 transform: true
以便它不再是 JSON 或字符串,而是实际的 class.
现在可以传入了
?filters={"userIds"=["1","2","5"],"ages"=["25"]}
它会在尝试传入时成功
?filters={"blaBla"=["1","2","5"],"ages"=[25]}
它会失败。
我用打字稿项目构建了 nestjs,我正在尝试验证过滤器查询参数。 我只希望过滤键和值可以通过验证。 良好参数的示例:通过验证
any-endpoint?filters={"userIds"=["1","2","5"],"ages"=[25]}
any-endpoint?filters={"names"=["david","samuel"],"ages"=[21]}
错误参数示例:验证失败
any-endpoint?filters={"blaBla"=["1","2","5"],"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
我的代码
import { IsNumber, IsOptional,IsArray, IsString } from 'class-validator';
class FiltersOptionsDto {
@IsOptional()
@IsArray()
@IsString({ each: true })
userIds?: string[];
@IsOptional()
@IsArray()
@IsString({ each: true })
ages?: number[];
@IsOptional()
@IsArray()
@IsNumber({}, { each: true })
names?: string[];
}
export class AQueryDto {
@IsOptional()
// what to add here?
filters?: FiltersOptionsDto;
}
怎么做?
还没有测试过,但是从 docs 我认为这就是你需要的:
export class AQueryDto {
@IsOptional()
@ValidateNested() // +
filters?: FiltersOptionsDto;
}
好吧,所以如果你真的想以那种格式发送查询,你可以使用 class-transformer
中的 @Transform()
装饰器并使用 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 格式(我也分开了 classes 因为我更喜欢一个class 每个文件)。通过以上,传入 filters
的值将从字符串值获取到 JSON(普通),然后从普通到 class.
- 您需要在
ValidationPipe
中设置forbidNonWhitelisted: true
。我是这样做的:
@Module({
providers: [
{
provide: APP_PIPE,
useValue: new ValidationPipe({ forbidNonWhitelisted: true })
}
]
})
export class AppModule {}
(当然还有其他提供者和控制者)。我还想添加 transform: true
以便它不再是 JSON 或字符串,而是实际的 class.
现在可以传入了
?filters={"userIds"=["1","2","5"],"ages"=["25"]}
它会在尝试传入时成功
?filters={"blaBla"=["1","2","5"],"ages"=[25]}
它会失败。