Class-validator - validate array of objects

非 Y 不嫁゛ 提交于 2020-05-25 17:22:18

问题


I am using class-validator package with NestJS and I am looking to validate an array of objects that need to have exactly 2 objects with the same layout:

So far I have:

import { IsString, IsNumber } from 'class-validator';

export class AuthParam {
  @IsNumber()
  id: number;

  @IsString()
  type: string;

  @IsString()
  value: string;
}

and

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

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

per @kamilg response (I am able to enforce exacly 2 elements):

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[];
}

I still can pass an empty array or an array with some other objects not related to AuthParam.

How I should modify it get validation?

Also how I can enforce mandatory 2 elements in the array? MinLength(2) seems to be regarding string... (resolved)


回答1:


Add @Type(() => AuthParam) to your array and it should be working. Type decorator is required for nested objects(arrays). Your code becomes

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[];
}

Be careful if you are using any exception filter to modify the error reponse. Make sure you understand the structure of the class-validator errors.




回答2:


You can use the following:

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)

You may want to consider writing custom validator which would better reflect the business requirement you have.




回答3:



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])
})

This works correctly, this is:

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

so I may only assume that object which is being validated, is not an instance of AuthParam

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

as expected, there aren't any decorators on this object (which may be true for Nest.js controllers and nested objects from body/req) - so validation is ignored.

Please check this (tl;dr - @Type decorator form class-transformer)




回答4:


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

Was just published in v0.10.2, so it should help, hopefully!



来源:https://stackoverflow.com/questions/58343262/class-validator-validate-array-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!