使用 class-transformer 将字符串化的 JSON 转换为对象
Convert stringified JSON to Object using class-transformer
有一个 nest.js 项目,在请求正文中我们期望一个对象,该对象的一个 属性 包含字符串化的 JSON 值。这个想法是将这个字符串转换为一个对象,验证它并作为一个对象传递给控制器
验证管道设置:
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
transform: true,
}),
);
DTO:
@Transform(parseJson, { toClassOnly: true })
@Type(() => AdditionalInfo)
@IsNotEmptyObject()
@ValidateNested()
additionalInfo: AdditionalInfo;
parseJson 函数
export function parseJson(options: {
key: string;
value: string;
obj: string | Record<string, any>;
}): Record<string, any> {
try {
return JSON.parse(options.value);
} catch (e) {
throw new BadRequestException(`${options.key} contains invalid JSON `);
}
}
出于某种原因,在控制器中解析的值丢失了,我们收到一个空对象。
看起来 @Transform
只适用于原语。
决定创建 ParseJsonPipe
并改为使用它。
用法(在控制器中):
@Body('additionalInfo', new ParseJsonPipe(), new ValidationPipe(AdditionalInfoDto)) additionalInfo: AdditionalInfo,
ParseJsonPipe:
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ParseJsonPipe implements PipeTransform<string, Record<string, any>> {
transform(value: string, metadata: ArgumentMetadata): Record<string, any> {
const propertyName = metadata.data;
try {
return JSON.parse(value);
} catch (e) {
throw new BadRequestException(`${propertyName} contains invalid JSON `);
}
}
}
ValidationPipe
从 @nestjs/common
实现 PipeTransform
,transform
函数看起来像这样:
async transform(value: any): Promise<any> {
if (!this.metaType) { // AdditionalInfoDto
return value;
}
const object = plainToClass(this.metaType, value);
const errors = await validate(object);
if (errors.length > 0) {
const message = this.getErrorMessages(errors);
throw new BadRequestException({ message });
}
return value;
}
有一个 nest.js 项目,在请求正文中我们期望一个对象,该对象的一个 属性 包含字符串化的 JSON 值。这个想法是将这个字符串转换为一个对象,验证它并作为一个对象传递给控制器 验证管道设置:
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
transform: true,
}),
);
DTO:
@Transform(parseJson, { toClassOnly: true })
@Type(() => AdditionalInfo)
@IsNotEmptyObject()
@ValidateNested()
additionalInfo: AdditionalInfo;
parseJson 函数
export function parseJson(options: {
key: string;
value: string;
obj: string | Record<string, any>;
}): Record<string, any> {
try {
return JSON.parse(options.value);
} catch (e) {
throw new BadRequestException(`${options.key} contains invalid JSON `);
}
}
出于某种原因,在控制器中解析的值丢失了,我们收到一个空对象。
看起来 @Transform
只适用于原语。
决定创建 ParseJsonPipe
并改为使用它。
用法(在控制器中):
@Body('additionalInfo', new ParseJsonPipe(), new ValidationPipe(AdditionalInfoDto)) additionalInfo: AdditionalInfo,
ParseJsonPipe:
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ParseJsonPipe implements PipeTransform<string, Record<string, any>> {
transform(value: string, metadata: ArgumentMetadata): Record<string, any> {
const propertyName = metadata.data;
try {
return JSON.parse(value);
} catch (e) {
throw new BadRequestException(`${propertyName} contains invalid JSON `);
}
}
}
ValidationPipe
从 @nestjs/common
实现 PipeTransform
,transform
函数看起来像这样:
async transform(value: any): Promise<any> {
if (!this.metaType) { // AdditionalInfoDto
return value;
}
const object = plainToClass(this.metaType, value);
const errors = await validate(object);
if (errors.length > 0) {
const message = this.getErrorMessages(errors);
throw new BadRequestException({ message });
}
return value;
}