5

我有一个代码,我在main.ts文件中应用了一个全局验证管道,如下所示:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  // Enable global validation pipe
  app.useGlobalPipes(new ValidationPipe({
    whitelist: true
  }));
}

现在在我的一个控制器中,我想在补丁请求中跳过 DTO 的一些属性,如下所示

    @Patch(':id')
    // Override the pipes
    @UsePipes(new ValidationPipe({
        skipMissingProperties: true,
    }))
    updateProject(@Param('id') accountId: string, @Body() dataToUpdate: UpdateProjectDTO) {
        return dataToUpdate;
    }

这是我的 DTO:

export class UpdateProjectDTO {
    @IsNotEmpty()
    projectType: string;

    @IsNotEmpty()
    projectDescription: string;
}

projectDescription如果它没有作为请求的一部分提交,我想忽略它。但在这种情况下,我的全局管道优先,它没有被skipMissingProperties定义为其属性的一部分。是否有覆盖全局管道的解决方案?

4

2 回答 2

0

将您的装饰器更改为@IsOptional()from@IsNotEmpty()

于 2021-04-01T13:31:10.793 回答
0

覆盖全局验证管道很棘手。对我有用的解决方案是为特定的参数装饰器覆盖它。下面的示例适用于主体,但该原理也可以应用于其他装饰器。

首先,创建一个 raw body 自定义装饰器:

export const RawBody = createParamDecorator(
  (data: unknown, ctx: ExecutionContext): any => {
    const request = ctx.switchToHttp().getRequest();
    return request.body;
  }
);

其次,编写另一个自定义装饰器,用一个新的验证管道组成它:

export const AnyValidBody = () =>
  RawBody(
    new ValidationPipe({
      validateCustomDecorators: true,
      whitelist: true,
      skipMissingProperties: true
    })
  );

现在,在您的控制器中使用@AnyValidBody而不是@Body像这样:

    @Patch(':id')
    updateProject(@Param('id') accountId: string, @AnyValidBody() dataToUpdate: UpdateProjectDTO) {
        return dataToUpdate;
    }

有关解决此问题的其他方法,请查看:https ://gist.github.com/josephdpurcell/9af97c36148673de596ecaa7e5eb6a0a 。它也有其他类似堆栈溢出问题的链接。

于 2021-11-19T18:21:43.843 回答