class-验证器在 NestJS 应用程序中似乎没有做任何事情
class-validator doesn't appear to do anything in NestJS application
我正在设置一个新的 NestJS 应用程序,我刚刚添加了 class-validator 以验证控制器输入,但它似乎被完全忽略了。这是 DTO:
import {IsString} from 'class-validator';
export class CreateCompanyDto {
@IsString()
name: string | undefined;
}
这是控制器:
import {
Body,
Controller,
InternalServerErrorException,
Post,
Request,
UseGuards, ValidationPipe
} from '@nestjs/common';
import * as admin from 'firebase-admin';
import {User} from 'firebase';
import {AuthGuard} from '../auth/auth.guard';
import {CurrentUser} from '../auth/current-user.decorator';
import {CreateCompanyDto} from './dto/create-company.dto';
@Controller('vendor')
export class VendorController {
@Post()
@UseGuards(AuthGuard)
async create(@CurrentUser() user: User, @Request() req: any, @Body(new ValidationPipe({ transform: true })) company: CreateCompanyDto) {
console.log(JSON.stringify(company));
throw new InternalServerErrorException('meh?');
// irrelevant code
}
}
我希望代码抛出验证错误并且永远不会命中方法本身,但它会遇到异常,并且对象会完全按照它进来的样子被记录下来。
package.json:
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"prebuild": "(cd src && rm settings.json && ln -s ../configs/prod.json settings.json)",
"build": "tsc",
"prebuild:dev": "(cd src && rm settings.json && ln -s ../configs/dev.json settings.json)",
"build:dev": "tsc",
"serve": "concurrently \"npm run build:dev -- --watch\" \"firebase emulators:start --only functions\"",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/functions/src/index.js",
"dependencies": {
"@elastic/elasticsearch": "^7.6.0",
"@nestjs/common": "^6.11.11",
"@nestjs/core": "^6.11.11",
"@nestjs/platform-express": "^6.11.11",
"@types/airtable": "^0.5.7",
"@types/nodemailer": "^6.4.0",
"airtable": "^0.8.1",
"class-transformer": "^0.2.3",
"class-validator": "^0.11.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase": "^7.10.0",
"firebase-admin": "^8.9.2",
"firebase-functions": "^3.3.0",
"nodemailer": "^6.4.4",
"reflect-metadata": "^0.1.13",
"rxjs": "^6.5.4",
"slugify": "^1.4.0"
},
"devDependencies": {
"concurrently": "^5.1.0",
"tslint": "^6.0.0",
"typescript": "~3.7.5"
},
"private": true
}
我在这里错过了什么?
更新
我做了一些调试,虽然我仍然不知道为什么,但我可以知道哪里出了问题。
在 ValidationPipe.transform 方法中,它 returns 原始输入,因为元类型未定义:
async transform(value, metadata) {
const { metatype } = metadata;
if (!metatype || !this.toValidate(metadata)) {
return value;
}
// ...
}
当然,调试给了我足够的信息来找到 Google 上的问题,我在那里发现了这个 Github 问题:https://github.com/nestjs/nest/issues/690
您需要在 tsconfig.json
文件中启用 "emitDecoratorMetadata": true
才能正常工作。
在 main.ts
添加 app.useGlobalPipes(new ValidationPipe());
:
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT || 3000);
}
bootstrap();
我正在设置一个新的 NestJS 应用程序,我刚刚添加了 class-validator 以验证控制器输入,但它似乎被完全忽略了。这是 DTO:
import {IsString} from 'class-validator';
export class CreateCompanyDto {
@IsString()
name: string | undefined;
}
这是控制器:
import {
Body,
Controller,
InternalServerErrorException,
Post,
Request,
UseGuards, ValidationPipe
} from '@nestjs/common';
import * as admin from 'firebase-admin';
import {User} from 'firebase';
import {AuthGuard} from '../auth/auth.guard';
import {CurrentUser} from '../auth/current-user.decorator';
import {CreateCompanyDto} from './dto/create-company.dto';
@Controller('vendor')
export class VendorController {
@Post()
@UseGuards(AuthGuard)
async create(@CurrentUser() user: User, @Request() req: any, @Body(new ValidationPipe({ transform: true })) company: CreateCompanyDto) {
console.log(JSON.stringify(company));
throw new InternalServerErrorException('meh?');
// irrelevant code
}
}
我希望代码抛出验证错误并且永远不会命中方法本身,但它会遇到异常,并且对象会完全按照它进来的样子被记录下来。
package.json:
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"prebuild": "(cd src && rm settings.json && ln -s ../configs/prod.json settings.json)",
"build": "tsc",
"prebuild:dev": "(cd src && rm settings.json && ln -s ../configs/dev.json settings.json)",
"build:dev": "tsc",
"serve": "concurrently \"npm run build:dev -- --watch\" \"firebase emulators:start --only functions\"",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/functions/src/index.js",
"dependencies": {
"@elastic/elasticsearch": "^7.6.0",
"@nestjs/common": "^6.11.11",
"@nestjs/core": "^6.11.11",
"@nestjs/platform-express": "^6.11.11",
"@types/airtable": "^0.5.7",
"@types/nodemailer": "^6.4.0",
"airtable": "^0.8.1",
"class-transformer": "^0.2.3",
"class-validator": "^0.11.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase": "^7.10.0",
"firebase-admin": "^8.9.2",
"firebase-functions": "^3.3.0",
"nodemailer": "^6.4.4",
"reflect-metadata": "^0.1.13",
"rxjs": "^6.5.4",
"slugify": "^1.4.0"
},
"devDependencies": {
"concurrently": "^5.1.0",
"tslint": "^6.0.0",
"typescript": "~3.7.5"
},
"private": true
}
我在这里错过了什么?
更新 我做了一些调试,虽然我仍然不知道为什么,但我可以知道哪里出了问题。
在 ValidationPipe.transform 方法中,它 returns 原始输入,因为元类型未定义:
async transform(value, metadata) {
const { metatype } = metadata;
if (!metatype || !this.toValidate(metadata)) {
return value;
}
// ...
}
当然,调试给了我足够的信息来找到 Google 上的问题,我在那里发现了这个 Github 问题:https://github.com/nestjs/nest/issues/690
您需要在 tsconfig.json
文件中启用 "emitDecoratorMetadata": true
才能正常工作。
在 main.ts
添加 app.useGlobalPipes(new ValidationPipe());
:
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT || 3000);
}
bootstrap();