Пройдите проверку @IsInt() для типа запроса application/x-www-form-urlencoded
Когда я просмотрел документацию по Pipes, я заметил, что не могу сделать @IsInt()
проверка правильности запроса application/x-www-form-urlencoded, потому что все значения, которые я передал, я получаю как строковые значения.
Мои данные запроса выглядят так
Мой DTO выглядит так
import { IsString, IsInt } from 'class-validator';
export class CreateCatDto {
@IsString()
readonly name: string;
@IsInt()
readonly age: number;
@IsString()
readonly breed: string;
}
Труба проверки содержит следующий код
import { PipeTransform, Pipe, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';
@Pipe()
export class ValidationPipe implements PipeTransform<any> {
async transform(value, metadata: ArgumentMetadata) {
const { metatype } = metadata;
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToClass(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException('Validation failed');
}
return value;
}
private toValidate(metatype): boolean {
const types = [String, Boolean, Number, Array, Object];
return !types.find((type) => metatype === type);
}
}
Когда я отлаживал эту трубу, я заметил это состояние Куда:
- value - значение тела запроса
- объект - преобразован через значение класса-преобразователя
- ошибки - объект ошибки
Как видите, ошибки говорят нам, что возраст должен быть целым числом.
Как я могу пройти @IsInt()
проверка для заявки / x-www-form-urlencoded запроса?
Версии библиотек:
- @ nestjs / общие @ 4.6.4
- class-transformer@0.1.8
- class-validator@0.8.1
PS: Я также создаю репозиторий, где вы можете запустить приложение для проверки ошибок. Обязательная ветка how-to-pass-int-validation
UPD: после внесения изменений в принятый ответ я столкнулся с проблемой, связанной с неправильным анализом данных в хранилище. Записанный пример
Можно ли разобраться? createCatDto
или что мне нужно сделать, чтобы сохранить его с правильной структурой типа?
2 ответа
Все значения из application/x-www-form-urlencoded
запрос всегда строки.
Итак, вы можете сделать следующее:
import { Transform } from 'class-transformer';
import { IsString, IsInt } from 'class-validator';
export class CreateCatDto {
@IsString()
readonly name: string;
@Transform(value => Number.isNan(+value) ? 0 : +value) // this field will be parsed to integer when `plainToClass gets called`
@IsInt()
readonly age: number;
@IsString()
readonly breed: string;
}
Добавление @Type(() => Number) решило проблему для меня.
import { Type } from 'class-transformer';
import { IsInt, IsNotEmpty } from 'class-validator';
@IsNotEmpty({ message: '' })
@Type(() => Number)
@IsInt({ message: '' })
project: number;