Nestjs FileInterceptor和DTO
我想用Swagger创建上传,使用DTO并将二进制保存在我的dto中
:
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsNotEmpty, IsOptional } from 'class-validator';
export class GatewayDto {
@ApiProperty({ default: 'foo' })
@IsNotEmpty()
@Expose()
name: string;
@ApiProperty({default: 'XXXX:YYYY'})
@IsNotEmpty()
@Expose()
token: string;
@ApiProperty({default: '123'})
@IsNotEmpty()
@Expose()
channelId: string;
@ApiProperty({ default: true })
@IsNotEmpty()
@Expose()
public: string;
@Expose()
@IsNotEmpty()
logo: any;
}
我的控制器是:
@Post('/')
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
name: {
type: 'string',
default: 'foo'
},
token: {
type: 'string',
default: '11:22'
},
channelId: {
type: 'string',
default: '1234'
},
public: {
type: 'string',
default: 'true'
},
logo: {
type: 'string',
format: 'binary',
},
},
},
})
@UseInterceptors(FileInterceptor('logo'))
@HttpCode(HttpStatus.CREATED)
@ApiCreatedResponse(GatewayConfigSwagger.API_CREATE_GATEWAY)
//@Serialize(GatewayDto)
public async create(
@UploadedFile('file') file,
@Body() data: GatewayDto,
@Request() request
) {
console.log(data);
if (file) {
data['logo'] = file.buffer;
}
//return this.gatewayService.create(request.user.userId._id, data);
}
当我创建我的请求时,我会收到此错误:
“徽标不应该为空”
>
我的卷发是:
curl -X 'POST' \
'http://localhost:3001/api/v1/gateways' \
-H 'accept: application/json' \
-H 'Authorization: Bearer xxx \
-H 'Content-Type: multipart/form-data' \
-F 'name=foo' \
-F 'token=11:22' \
-F 'channelId=1234' \
-F 'public=true' \
-F '[email protected];type=image/png'
如果我从DTO删除徽标字段,则可以存储图像。
我试图根据此答案创建一个拦截器 Swagger Nestjs中的其他数据
import { BadGatewayException, CallHandler, ExecutionContext, Injectable, NestInterceptor, UnauthorizedException } from "@nestjs/common";
import { catchError, map, Observable, throwError } from "rxjs";
export interface Response<T> {
statusCode: number;
data: T;
}
@Injectable()
export class FileExtender implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const req = context.switchToHttp().getRequest();
console.log(req.body)
return next.handle();
}
}
和我的req.body没有徽标字段
更新
我更新了我的Interceptor
import { BadGatewayException, CallHandler, ExecutionContext, Injectable, NestInterceptor, UnauthorizedException } from "@nestjs/common";
import { catchError, map, Observable, throwError } from "rxjs";
export interface Response<T> {
statusCode: number;
data: T;
}
@Injectable()
export class FileExtender implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const req = context.switchToHttp().getRequest();
req.body['logo'] = req.file.buffer;
console.log(req.body)
return next.handle();
}
}
现在它有效,但这是最好的做法吗?
I want to create upload with swagger,use DTO and save the binary in my MongoDB
My DTO is:
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsNotEmpty, IsOptional } from 'class-validator';
export class GatewayDto {
@ApiProperty({ default: 'foo' })
@IsNotEmpty()
@Expose()
name: string;
@ApiProperty({default: 'XXXX:YYYY'})
@IsNotEmpty()
@Expose()
token: string;
@ApiProperty({default: '123'})
@IsNotEmpty()
@Expose()
channelId: string;
@ApiProperty({ default: true })
@IsNotEmpty()
@Expose()
public: string;
@Expose()
@IsNotEmpty()
logo: any;
}
my controller is:
@Post('/')
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
name: {
type: 'string',
default: 'foo'
},
token: {
type: 'string',
default: '11:22'
},
channelId: {
type: 'string',
default: '1234'
},
public: {
type: 'string',
default: 'true'
},
logo: {
type: 'string',
format: 'binary',
},
},
},
})
@UseInterceptors(FileInterceptor('logo'))
@HttpCode(HttpStatus.CREATED)
@ApiCreatedResponse(GatewayConfigSwagger.API_CREATE_GATEWAY)
//@Serialize(GatewayDto)
public async create(
@UploadedFile('file') file,
@Body() data: GatewayDto,
@Request() request
) {
console.log(data);
if (file) {
data['logo'] = file.buffer;
}
//return this.gatewayService.create(request.user.userId._id, data);
}
When I create my request, I get this error:
"logo should not be empty"
My curl is:
curl -X 'POST' \
'http://localhost:3001/api/v1/gateways' \
-H 'accept: application/json' \
-H 'Authorization: Bearer xxx \
-H 'Content-Type: multipart/form-data' \
-F 'name=foo' \
-F 'token=11:22' \
-F 'channelId=1234' \
-F 'public=true' \
-F '[email protected];type=image/png'
If I remove the logo field from DTO I'm able to store my image.
I tried to create a interceptor according to this answer File uploading along with other data in Swagger NestJs
import { BadGatewayException, CallHandler, ExecutionContext, Injectable, NestInterceptor, UnauthorizedException } from "@nestjs/common";
import { catchError, map, Observable, throwError } from "rxjs";
export interface Response<T> {
statusCode: number;
data: T;
}
@Injectable()
export class FileExtender implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const req = context.switchToHttp().getRequest();
console.log(req.body)
return next.handle();
}
}
and my req.body doesn't have logo field
UPDATE
I updated my interceptor with
import { BadGatewayException, CallHandler, ExecutionContext, Injectable, NestInterceptor, UnauthorizedException } from "@nestjs/common";
import { catchError, map, Observable, throwError } from "rxjs";
export interface Response<T> {
statusCode: number;
data: T;
}
@Injectable()
export class FileExtender implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const req = context.switchToHttp().getRequest();
req.body['logo'] = req.file.buffer;
console.log(req.body)
return next.handle();
}
}
Now it works, but is it the best practice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试在DTO文件中使用
@isoptional
在徽标
属性上使用验证器。它用于标记无效字段。验证将通过它是null
或undefined
,并且将按照其他验证器执行。应用逻辑必须相应处理。您可以查看所有可用的验证器在这里。您可以在任何DTO类属性上组合其中的任何数量。
Try using the
@IsOptional
validator on thelogo
property in the DTO file. It is used to mark nullable fields. Validation will pass if it isnull
orundefined
and will be enforced as per other validators otherwise. Application logic must handle this accordingly.You can take a look at all available validators here. You can combine any number of them on any DTO class property.