When trying to validate nested objects using @ValidateNested(), whitelist: true and forbidNonWhitelisted: true, error "property XY should not exist" gets thrown for no apparent reason.
Here a vastly simplified version of my use case:
class ProductPricing {
@Type(() => ProductPricingOptionsDTO)
options: ProductPricingOptionsDTO;
}
class ProductPricingOptionsDTO{
@ValidateNested()
@Type(() => OnlineUserPricingOptionsDTO)
onlineUserPrices: OnlineUserPricingOptionsDTO;
}
md5-a0958fc4778dd0b00617aaa166cdc454
class OnlineUserPricingOptionsDTO{
@IsNumber()
@Min(2)
price: number;
}
md5-2423009a39f75b49cb1b947056fbcdcf
{
"options": {
"onlineUserPrices": {
"price": 2
}
}
}
md5-4429c47492cdac6fe03394825f60a785
"constraints": {
"whitelistValidation": "property price should not exist" }
}
class-validator version: ^0.12.1
Setting only forbidNonWhitelisted: true is necessary to reproduce this problem, that will throw the property X should not exist message
For setting only forbidUnknownValues: true, the class-validator will throw with an unknown value was passed to the validate
If both options are enabled, it will give an error in the first check rule
For example:
If my PipeValidation is
new ValidationPipe({
whitelist: true,
forbidUnknownValues: true,
forbidNonWhitelisted: true,
})
It will throw the forbidUnknownValues message because it's the first rule checked at ValidationPipe, the same occurs if forbidNonWhitelisted is above forbidUnknown but it will throw property X should not exist message instead
Any updates on this?
Just hit this issue...
Hi!
I had the same issue but I managed to resolve it by using:
transformOptions: {
enableImplicitConversion: true,
},
Please let me know if it helped also in your cases.
It works in terms of passing the validation, but... It does not validate the nested objects at all now :/
@IsNotEmpty()
@IsArray()
@ArrayNotEmpty()
@ValidateNested({ each: true })
myNestedObjects!: NestedObjectType[]
export class NestedObjectType{
@IsNotEmpty()
@IsString()
firstName!: string;
@IsNotEmpty()
@IsString()
lastName!: string;
}
I can miss fields or pass wrong values - validation still passes without any issue :/
I tested such example
export class Address {
@IsString()
public street!: string;
}
export class CreateParams {
@IsString()
public name!: string;
@IsIn(Object.values(Gender))
@ApiProperty({ enum: Gender, enumName: GENDER_ENUM_NAME })
public gender!: Gender;
@IsPositive()
public age!: number;
@ValidateNested()
@Type(() => Address)
public address!: Address;
}
And it validated address correctly for optimistic/pessimistic paths.
Cheers! We have found out that adding @Type(() => NestedType) was the thing. It works without adding that parameter which you suggested.
Adding comment for "future generations".
Ok. Update on my case. @Type decorator didn't work as should when used yarn link along with class-transformer in peerDependency. So option enableImplicitConversion: true helped me because of not working @Type but when not linked everything works as it should 馃憤 .
@murbanowicz adding @Type(() => NestedType) seems to only be working on second level objects. If you go down one more level like in the OP validation doesn't work on the third level object. I will try @gabrieloczkowski suggestion for enableImplicitConversion: true today and see if it works.
@gabrieloczkowski enableImplicitConversion: true did not work for me. Could you share an example of your implementation?
@gabrieloczkowski
enableImplicitConversion: truedid not work for me. Could you share an example of your implementation?
@rbiggers
https://github.com/typestack/class-validator/issues/614#issuecomment-698336485
{
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
transform: true,
transformOptions: {
enableImplicitConversion: true,
},
}
@gabrieloczkowski Where did you enable these attributes? I can only find the first three attributes in the configuration when validating with validate() of class-validator.
@jpabeem configurations which @gabrieloczkowski wrote are forValidationPipe which is used in nestjs
Thanks! Makes sense. Hope we can get support for deeply-nested validation in a future release :-)
Most helpful comment
Cheers! We have found out that adding
@Type(() => NestedType)was the thing. It works without adding that parameter which you suggested.Adding comment for "future generations".