Nodejs,一个未知的值被传递给了validate函数,但我找不到有什么问题



感谢您的帮助。我有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在这里有一个关于这方面的部分。

相关内容

  • 没有找到相关文章

最新更新