我正在努力使我的请求dto的字段不区分大小写。
export class ExampleDto {
dateOfBirth?: string
}
现在我想接受
{ "dateofbirth": "19880101" }
{ "dateOfBirth": "19880101" }
{ "DATEOFBIRTH": "19880101" }
我的第一个想法是实现一个中间件,它只查看传入的正文并"扩展"它。与低&所有输入字段的大写映射。
但由于驼峰大小写,这不符合我的要求,我绝对希望保持默认值
有什么好主意吗?
您可以创建一个自定义Pipe
,在其中尝试不同的选项并最终返回Dto实例:
export class CaseInsensitiveExampleDtoPipe implements PipeTransform{
transform(body: any, metadata: ArgumentMetadata): ExampleDto {
const dto = new ExampleDto();
dto.dateOfBirth = body.dateOfBirth || body.dateofbirth || body.DATEOFBIRTH;
return dto;
}
在你的控制器中,你可以这样使用它:
@UsePipes(new CaseInsensitiveExampleDtoPipe())
async postNewExample(@Body() exampleDto: ExampleDto) {
// ...
}
由于JavaScript属性在初始化后就开始存在,因此您无法"看到"。dateOfBirth?: string
的定义,因此您将无法将其与收到的JSON进行匹配。
export class ExampleDto {
dateOfBirth: string
constructor(dateOfBirth: string){
this.dateOfBirth = dateOfBirth;
}
}
然后,您将能够遍历ExampleDto
的属性并将它们与管道匹配(接收到的类型可以从metadata
派生):
@Injectable()
export class IgnoreCasePipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const dto = new metadata.metatype;
const dtoKeys = Object.getOwnPropertyNames(dto);
Object.keys(value).forEach(key => {
const realKey = dtoKeys.find(dtoKey => dtoKey.toLocaleLowerCase() === key.toLocaleLowerCase());
if (realKey) {
dto[realKey] = value[key];
}
});
return dto;
}
}
在main中全局注入。请记住,您需要为每个DTO创建一个构造函数。
注意:这将适用于单级类。如果你想在你的类中支持people: PersonDto[]
之类的东西,那么你需要递归地找到所有嵌套的键并匹配它们——就像这样。