未找到 class-验证器的元数据

No metadata found for class-validator

我正在尝试使用 ValidationPipe,但无论我如何编写代码,在发送请求时都会收到以下警告:No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies.

我的路线是这样的:

@Get()
@UsePipes(new ValidationPipe({ transform: true }))
async findAll(@Query() queryDto: QueryDto) {
    return await this.myService.findAll(queryDto);
}

我的 DTO 看起来像这样:

export class queryDto
{
    @ApiModelProperty({
        description: 'Maximum number of results',
        type: Number,
        example: 50,
        default: 50,
        required: false
    })
    readonly limit: number = 50;
}

我尝试使用 ValidationPipe 的几种方式,遵循 the doc,但对我来说没有任何效果。我知道它不起作用,因为虽然请求得到响应,但我在 DTO 中为 属性 limit 编写的默认值 50 在查询时未使用是空的。因此,当查询中没有提供 limit 时,limit 的值是未定义的,而它应该是 50 (这意味着 ValidationPipe 没有被使用)。

我的 package.json 似乎是正确的:

npm ls class-validator
api-sport@0.0.1 /home/pierre_t/Bureau/dev/ApiSport
└── class-validator@0.9.1

完整 package.json:

{
  "name": "api-sport",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "license": "MIT",
  "scripts": {
    "build": "tsc -p tsconfig.build.json",
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "start:prod": "pm2 start ./src/main.js --no-daemon",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^6.0.5",
    "@nestjs/core": "^6.0.5",
    "@nestjs/platform-express": "^6.0.5",
    "@nestjs/swagger": "^3.0.1",
    "@nestjs/typeorm": "^6.0.0",
    "@types/lodash": "^4.14.123",
    "class-transformer": "^0.2.0",
    "class-validator": "^0.9.1",
    "dotenv": "^7.0.0",
    "hbs": "^4.0.3",
    "mysql": "^2.16.0",
    "pm2": "^3.4.1",
    "reflect-metadata": "^0.1.12",
    "rimraf": "^2.6.2",
    "rxjs": "^6.3.3",
    "swagger-ui-express": "^4.0.2",
    "typeorm": "^0.2.16"
  },
  "devDependencies": {
    "@nestjs/testing": "^6.0.5",
    "@types/express": "^4.16.0",
    "@types/jest": "^23.3.13",
    "@types/node": "^10.14.4",
    "@types/supertest": "^2.0.7",
    "jest": "^23.6.0",
    "nodemon": "^1.18.9",
    "prettier": "^1.15.3",
    "supertest": "^3.4.1",
    "ts-jest": "^23.10.5",
    "ts-node": "^7.0.1",
    "tsconfig-paths": "^3.7.0",
    "tslint": "5.12.1",
    "typescript": "^3.4.1"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

为什么我会收到此消息以及如何使用 ValidationPipe

这是因为您正在使用 class-validator 但没有任何验证,请参阅此 issue:

Basically, it warns that you don't have any metadatas in the storage, which means you haven't used any decorator from class-validator. That means you don't perform any validation, so you should just pass validate: false option to buildSchema to disable automatic validation.

我不确定你是否可以关闭 nest 的验证 ValidationPipe,但是你也可以只向你的 dto 添加一个断言(如果它有意义的话),例如:

import { Min } from 'class-validator';
export class QueryDto {
    @Min(1)
    readonly limit: number = 50;
}

顺便说一下:由于您的 @Query 将只有字符串属性,您可能希望将 limitstring 转换为 number。看看这个 .

问题已经得到解答,供以后有相同问题的人参考...

class-validator allows you to bypass the validation of certain property (whitelisting) 特殊标志来验证任何 属性.

作为 docs

This will strip all properties that don't have any decorators. If no other decorator is suitable for your property, you can use @Allow decorator

例如:

import {validate, Allow, Min} from "class-validator";

export class Post {

    @Allow()
    title: string;

    @Min(0)
    views: number;

    nonWhitelistedProperty: number;
}

这是我的 bootstrap,它与 class-validator:

一起使用
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();