Class-validator - 验证对象数组

Posted

技术标签:

【中文标题】Class-validator - 验证对象数组【英文标题】:Class-validator - validate array of objects 【发布时间】:2020-02-09 02:24:04 【问题描述】:

我正在将 class-validator 包与 NestJS 一起使用,并且我希望验证一个对象数组,这些对象需要恰好有 2 个具有相同布局的对象:

到目前为止我有:

import  IsString, IsNumber  from 'class-validator';

export class AuthParam 
  @IsNumber()
  id: number;

  @IsString()
  type: string;

  @IsString()
  value: string;

import  IsArray, ValidateNested  from 'class-validator';
import  AuthParam  from './authParam.model';

export class SignIn 
  @IsArray()
  @ValidateNested( each: true )
  authParameters: AuthParam[];

每个@kamilg 响应(我能够强制执行 2 个元素):

import  IsArray, ValidateNested, ArrayMinSize, ArrayMaxSize  from 'class-validator';
import  AuthParam  from './authParam.model';

export class SignInModel 
  @IsArray()
  @ValidateNested( each: true )
  @ArrayMinSize(2)
  @ArrayMaxSize(2)
  authParameters: AuthParam[];

我仍然可以传递一个空数组或一个包含与 AuthParam 无关的其他对象的数组。

我应该如何修改它以获得验证?

另外,我如何在数组中强制执行 2 个元素? MinLength(2) 似乎与字符串有关...(已解决)

【问题讨论】:

【参考方案1】:

@Type(() => AuthParam) 添加到您的阵列中,它应该可以工作。嵌套对象(数组)需要Type 装饰器。你的代码变成了

import  IsArray, ValidateNested, ArrayMinSize, ArrayMaxSize  from 'class-validator';
import  AuthParam  from './authParam.model';
import  Type  from 'class-transformer';

export class SignInModel 
  @IsArray()
  @ValidateNested( each: true )
  @ArrayMinSize(2)
  @ArrayMaxSize(2)
  @Type(() => AuthParam)
  authParameters: AuthParam[];

如果您使用任何异常过滤器来修改错误响应,请务必小心。确保您了解类验证器错误的结构。

【讨论】:

嗨,关于如何在查询参数中为数字数组实现这一点的任何想法?想象一下我试图验证 [www.url.com/path?ids=1,2,3] ,其中 [ids] 应该是一个数字数组,仅此而已。尝试转换您的答案,但到目前为止没有成功。【参考方案2】:

您可以使用以下内容:

validator.arrayNotEmpty(array); // Checks if given array is not empty.

validator.arrayMinSize(array, min); // Checks if array's length is at least `min` number.

(https://github.com/typestack/class-validator#manual-validation)

您可能需要考虑编写自定义验证器,以更好地反映您的业务需求。

【讨论】:

这很好地解决了元素数量问题 - 谢谢。数组内对象的验证仍然有效【参考方案3】:

我知道我迟到了,但遇到了一些类型问题,然后尝试另一种方法来实现:

export class AuthParam 
    @IsNumber()
    id: number;
  
    @IsString()
    type: string;
  
    @IsString()
    value: string;
  

验证函数

@ValidatorConstraint()
export class IsAuthArray implements ValidatorConstraintInterface 
    public async validate(authData: AuthParam[], args: ValidationArguments) 
        return Array.isArray(authData) && authData.reduce((a, b) => a && (typeof b.id === "number") && typeof b.type === "string" && typeof b.field === "string", true);
    


export class SignInModel 
    @IsNotEmpty()
    @IsArray()
    @ArrayMinSize(2)
    @ArrayMaxSize(2)
    @Validate(IsAuthArray, 
        message: "Enter valid value .",
    )
    authParameters: AuthParam[];
  

也许它会帮助某人?

【讨论】:

【参考方案4】:

const param1: AuthParam = Object.assign(new AuthParam(), 
  id: 1,
  type: 'grant',
  value: 'password'
)

const param2: AuthParam = Object.assign(new AuthParam(), 
  id: 1,
  type: 4,
  value: 'password'
)

const signInTest = new SignInModel()
signInTest.authParameters = [param1, param2]

validate(signInTest).then(e => 
  console.log(e[0].children[0].children[0])
)

这工作正常,这是:

ValidationError 
  target: AuthParam  id: 1, type: 4, value: 'password' ,
  value: 4,
  property: 'type',
  children: [],
  constraints:  isString: 'type must be a string'  

所以我只能假设正在验证的对象不是AuthParam

instance
const param2: AuthParam = 
  id: 1,
  type: 4,
  value: 'password'
 as any

正如预期的那样,这个对象上没有任何装饰器(这可能适用于 Nest.js 控制器和来自 body/req 的嵌套对象)——因此忽略了验证。

请检查this (tl;dr - @Type 装饰器表单class-transformer)

【讨论】:

【参考方案5】:

https://github.com/typestack/class-validator/pull/295

刚刚在v0.10.2 发布,希望对您有所帮助!

【讨论】:

以上是关于Class-validator - 验证对象数组的主要内容,如果未能解决你的问题,请参考以下文章

在 TypeScript 中使用 `class-validator` 确认密码

如何使用 NestJS 和 class-validator 手动测试输入验证

类验证器不验证实体

Class-Validator node.js提供自定义的错误信息

是否可以将 `class-validator` 与 antd `Form.useForm`() 一起使用?

在 nest.js 控制器中使用类验证器验证嵌套对象