在我的API中考虑此端点:
@Post('/convert')
@UseInterceptors(FileInterceptor('image'))
convert(
@UploadedFile() image: any,
@Body(
new ValidationPipe({
validationError: {
target: false,
},
// this is set to true so the validator will return a class-based payload
transform: true,
// this is set because the validator needs a tranformed payload into a class-based
// object, otherwise nothing will be validated
transformOptions: { enableImplicitConversion: true },
}),
)
parameters: Parameters,
) {
return this.converterService.start(image, parameters);
}
设置为parameters
参数的请求正文包含名为laserMode
的属性,该属性应为布尔类型,并且可以像 parameters DTO这样进行验证:
@IsDefined()
@IsBoolean()
public laserMode: boolean;
现在是奇怪的部分,当从PostMan发送请求时,其中:
laserMode = false
laserMode = cool
(布尔值以外的字符串)我注意到laserMode
总是设置为true ,并且这是在完成验证过程之后,因为当我 console.log 时,类的构造函数
export class Parameters {
...
constructor() {
console.log('this :', this);
}
...
}
我看不到财产!
注意:当从请求中删除
laserMode
时,将返回预期的验证错误(应定义,应为布尔值)。
// the logged instance 'this' in the constructor
this : Parameters {
toolDiameter: 1,
sensitivity: 0.95,
scaleAxes: 200,
deepStep: -1,
whiteZ: 0,
blackZ: -2,
safeZ: 2,
workFeedRate: 3000,
idleFeedRate: 1200,
laserPowerOn: 'M04',
laserPowerOff: 'M05',
invest: Invest { x: false, y: true }
}
// the logged laserMode value in the endpoint handler in the controller
parameters.laserMode in controller : true
// the logged laser value from the service
parameters.laserMode in service : true
答案 0 :(得分:5)
这就是我在设法保持布尔类型输入的同时解决问题的方法。
通过键引用原始对象而不是使用解构的值。
import { Transform } from 'class-transformer';
const ToBoolean = () => {
const toPlain = Transform(
({ value }) => {
return value;
},
{
toPlainOnly: true,
}
);
const toClass = (target: any, key: string) => {
return Transform(
({ obj }) => {
return valueToBoolean(obj[key]);
},
{
toClassOnly: true,
}
)(target, key);
};
return function (target: any, key: string) {
toPlain(target, key);
toClass(target, key);
};
};
const valueToBoolean = (value: any) => {
if (value === null || value === undefined) {
return undefined;
}
if (typeof value === 'boolean') {
return value;
}
if (['true', 'on', 'yes', '1'].includes(value.toLowerCase())) {
return true;
}
if (['false', 'off', 'no', '0'].includes(value.toLowerCase())) {
return false;
}
return undefined;
};
export { ToBoolean };
export class SomeClass {
@ToBoolean()
isSomething : boolean;
}
答案 1 :(得分:1)
这归因于选项enableImplicitConversion
。显然,所有字符串值都被解释为true
,甚至字符串'false'
也是如此。
有一个issue请求更改class-transformer
的行为。