感谢您的帮助。我有API在使用NodeJ,它有3个论点,它接受,但似乎在验证方面存在问题。当我调用API时,它会给我这个结果,
[{
"statusCode": 400,
"message": [
"an unknown value was passed to the validate function"
],
"error": "Bad Request"
}]
帮帮我,任何人都能说出这是怎么回事!
我提出了三个论点,按照的顺序
https://www.youtube.com/watch?v=C5Y3fpHg45U
1
JP
然后我的代码就来了
/**
* Gets Subtitle From Youtube
* @param getYoutubeSubtitleDto
*/
public async getSubtitle(
getYoutubeSubtitleDto: GetYoutubeSubtitleDto,
): Promise<Subtitle[]> {
const { videoId, lang, projectId } = getYoutubeSubtitleDto
return this.getOrCreateSubtitles(videoId, lang, projectId)
}
export class GetYoutubeSubtitleDto extends Video {
@ApiProperty()
@IsNumber()
@Type(() => Number)
projectId: number
@ApiProperty({ description: 'Translation Language' })
@IsString()
lang: string
}
export const YOUTUBE_LINK_REGEX = /http(?:s?)://(?:www.)?youtu(?:be.com/watch?v=|.be/)([w-_]*)(&(amp;)?[w?=]*)?/
export class Video {
@ApiProperty({ description: 'Youtube Link' })
@IsString()
@Matches(YOUTUBE_LINK_REGEX)
video: string
public get videoId(): string {
return YOUTUBE_LINK_REGEX.exec(this.video)[1]
}
}
对于任何正在寻找正确解决方案和解释的人,而不仅仅是一个绕过错误的解决方案。。。
当您注册了全局ValidationPipe
:时会发生此错误
/* main.ts */
app.useGlobalPipes(new ValidationPipe())
或本地(端点级别(:
@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async save(@Query() dto: SomeDto) { ... }
在这种情况下,NestJS验证请求参数,如果它与指定的类型不匹配,您将收到错误消息:
"一个未知值被传递给验证函数";。
在大多数情况下,您的请求包含一些端点签名中未预期/定义的附加数据,或者您只是缺少DTO或类的适当类型信息,这些信息应作为输入类型。
例如,如果您在控制器中有一个函数,定义如下:
@Get('/list')
async getList(@Query() dto: MyDto): Promise<List> {
return this.listService.getList(dto);
}
// ...
class MyDto {
@IsString()
name: string;
@IsString()
surname: string;
}
并且你会传入{name: 'A', surname: 'B', age: 42}
,你会得到一个错误,因为age
预计不会传入。
有时发现这些错误可能很耗时,帮助您解决问题的一个简单技巧是实现自定义exceptionFactory
并将其传递给ValidationPipe
,在那里您可以打印出包含一些额外元数据的错误:
/* main.ts */
app.useGlobalPipes(new ValidationPipe({exceptionFactory: (e) => {
console.error(e);
throw new BadRequestException('You shall not pass!');
}
}))
这不会解决你的问题,但至少会给你一个类型不正确的信息,你可以从那里开始。
推荐解决方案
如果您确信您正在传递正确的有效载荷,但不想像其他建议的那样设置forbidUnknownValues
,那么您的类/DTO中的一个或多个很可能缺少成功验证有效载荷所需的一些类型声明。对我来说,大多数时候我都缺少嵌套(非基元(属性或对象数组的正确类型定义。
import {IsString, ValidateNested} from 'class-validator';
import {Type} from 'class-transformer';
//...
// Primitive type
@IsString()
name: string;
// Nested objects
@Type(() => Coach)
coach: Coach;
// Validate array of objects/entities
@ValidateNested({ each: true })
@Type(() => Player)
players: Player[];
您可以在文档的"验证"一章中阅读有关请求验证的更多信息。
在main.ts/bootstrap/useGlobalPipes
中将forbidUnknownValues
标志设置为false
app.useGlobalPipes(
new ValidationPipe({
forbidUnknownValues: false
}),
);
如果有人在更新类验证器后遇到此错误。请在更改日志中查看正在进行的更改。除了以前的解决方案之外。在我的案例中,由于我没有验证DTO类,所以引发了错误。
错误的
class SampleDTO {
prop?: string;
}
纠正
class SampleDTO {
@IsString()
prop?: string;
}
您必须将白名单与forbidNonWhitelisted、结合使用
参考文献:
我们可以将可接受的属性列入白名单,并且任何未包含在白名单中的属性都会自动从生成的对象中剥离
或者,当存在非白名单属性时,您可以停止处理请求,并向用户返回错误响应。要启用此功能,请将forbidNonWhitelisted选项属性设置为true,并将白名单设置为true
这对我有效:
<ValidationOptions> {
forbidNonWhitelisted: true,
whitelist: true,
}
NestJS在这里有一个关于这方面的部分。