我正在尝试使用class-validator和NestJS来验证嵌套对象。我已经尝试通过使用class-transform的@Type
装饰器来遵循此thread,但没有任何运气。这就是我所拥有的:
DTO:
class PositionDto {
@IsNumber()
cost: number;
@IsNumber()
quantity: number;
}
export class FreeAgentsCreateEventDto {
@IsNumber()
eventId: number;
@IsEnum(FinderGamesSkillLevel)
skillLevel: FinderGamesSkillLevel;
@ValidateNested({ each: true })
@Type(() => PositionDto)
positions: PositionDto[];
}
我也在使用内置的nestjs验证管道,这是我的引导程序:
async function bootstrap() {
const app = await NestFactory.create(ServerModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(config.PORT);
}
bootstrap();
对于其他属性,它工作正常,对象数组是唯一不起作用的对象。
答案 0 :(得分:5)
您期望positions: [1]
掷出400,但可以接受。
根据此Github issue,这似乎是类验证器中的错误。如果您传入原始类型(boolean
,string
,number
,...)或array
而不是对象,则尽管输入有效,但不应该。
除了创建custom validation decorator之外,我看不到任何标准的解决方法:
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';
export function IsNonPrimitiveArray(validationOptions?: ValidationOptions) {
return (object: any, propertyName: string) => {
registerDecorator({
name: 'IsNonPrimitiveArray',
target: object.constructor,
propertyName,
constraints: [],
options: validationOptions,
validator: {
validate(value: any, args: ValidationArguments) {
return Array.isArray(value) && value.reduce((a, b) => a && typeof b === 'object' && !Array.isArray(b), true);
},
},
});
};
}
,然后在您的dto类中使用它:
@ValidateNested({ each: true })
@IsNonPrimitiveArray()
@Type(() => PositionDto)
positions: PositionDto[];
答案 1 :(得分:3)
对我来说,我可以使用'class-transformer'
import { Type } from 'class-transformer';
完整示例:
import {
MinLength,
MaxLength,
IsNotEmpty,
ValidateNested,
IsDefined,
IsNotEmptyObject,
IsObject,
IsString,
} from 'class-validator';
import { Type } from 'class-transformer';
class MultiLanguageDTO {
@IsString()
@IsNotEmpty()
@MinLength(4)
@MaxLength(40)
en: string;
@IsString()
@IsNotEmpty()
@MinLength(4)
@MaxLength(40)
ar: string;
}
export class VideoDTO {
@IsDefined()
@IsNotEmptyObject()
@IsObject()
@ValidateNested()
@Type(() => MultiLanguageDTO)
name!: MultiLanguageDTO;
}