gpt4 book ai didi

node.js - Class-Validator (Node.js) 在自定义验证中获取另一个属性值

转载 作者:行者123 更新时间:2023-12-05 01:53:56 30 4
gpt4 key购买 nike

目前,我在 Nest.js 中有一个非常简单的带有 ValidationPipe 的类验证器文件,如下所示:

import {
IsDateString,
IsEmail,
IsOptional,
IsString,
Length,
Max,
} from 'class-validator';

export class UpdateUserDto {
@IsString()
id: string;

@Length(2, 50)
@IsString()
firstName: string;

@IsOptional()
@Length(2, 50)
@IsString()
middleName?: string;

@Length(2, 50)
@IsString()
lastName: string;

@IsEmail()
@Max(255)
email: string;

@Length(8, 50)
password: string;

@IsDateString()
dateOfBirth: string | Date;
}

假设在上面的“UpdateUserDto”中,用户传递了一个“电子邮件”字段。我想通过类验证器构建自定义验证规则:

  • 检查电子邮件地址是否已被用户从数据库中获取
  • 如果电子邮件地址已被使用,则检查当前用户(使用“id”属性的值)是否正在使用它,如果是,则验证通过,否则,如果它已被其他用户使用,则验证失败。

虽然检查电子邮件地址是否已被使用是一项非常简单的任务,但您如何才能将 DTO 中其他属性的值传递给自定义装饰器 @IsEmailUsed

最佳答案

解决起来非常简单,我通过如下创建自定义类验证装饰器解决了这个问题:

import { PrismaService } from '../../prisma/prisma.service';
import {
registerDecorator,
ValidationOptions,
ValidatorConstraint,
ValidatorConstraintInterface,
ValidationArguments,
} from 'class-validator';
import { Injectable } from '@nestjs/common';

@ValidatorConstraint({ name: 'Unique', async: true })
@Injectable()
export class UniqueConstraint implements ValidatorConstraintInterface {
constructor(private readonly prisma: PrismaService) {}

async validate(value: any, args: ValidationArguments): Promise<boolean> {
const [model, property = 'id', exceptField = null] = args.constraints;

if (!value || !model) return false;

const record = await this.prisma[model].findUnique({
where: {
[property]: value,
},
});

if (record === null) return true;

if (!exceptField) return false;

const exceptFieldValue = (args.object as any)[exceptField];
if (!exceptFieldValue) return false;

return record[exceptField] === exceptFieldValue;
}

defaultMessage(args: ValidationArguments) {
return `${args.property} entered is not valid`;
}
}

export function Unique(
model: string,
uniqueField: string,
exceptField: string = null,
validationOptions?: ValidationOptions,
) {
return function (object: any, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [model, uniqueField, exceptField],
validator: UniqueConstraint,
});
};
}

但是,要允许 DI 到那个特定的装饰器,您还需要将其添加到您的 main.ts 引导函数中:

async function bootstrap() {
const app = await NestFactory.create(AppModule);

...
// Line below needs to be added.
useContainer(app.select(AppModule), { fallbackOnErrors: true });
...
}

此外,请确保在应用程序模块中导入“约束”:

@Module({
imports: ...,
controllers: [AppController],
providers: [
AppService,
PrismaService,
...,
// Line below added
UniqueConstraint,
],
})
export class AppModule {}

最后,将其添加到您的 DTO 中:

export class UpdateUserDto {
@IsString()
id: string;

@IsEmail()
@Unique('user', 'email', 'id') // Adding this will check in the user table for a user with email entered, if it is already taken, it will check if it is taken by the same current user, and if so, no issues with validation, otherwise, validation fails.
email: string;
}

关于node.js - Class-Validator (Node.js) 在自定义验证中获取另一个属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70907953/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com