繁体   English   中英

NestJS拦截器将URL参数映射到DTO不会将值转换为@Type(()=> Number)之后的数字

[英]NestJS Interceptor mapping URL parameters into DTO is not converting values to numbers following @Type( ()=> Number)

This question之后,我创建了一个拦截器,并且我能够将我的参数 map 到我的 DTO 中。 但是,数字参数在验证期间不会转换为数字。

DTO:

export class GetDTO {
    @IsDefined() @IsNumber() @Max(50) @Min(1) @Type( () => Number) public Start: number;
    @IsDefined() @IsString() @MaxLength(64) @MinLength(5) public Description: string;
    

Controller 定义了拦截器的本地副本

@UseInterceptors(AddParametersToRequestBodyInterceptor)
export class MyController {

@Post('/:Start')
public async GetData(
    @Param('Start', ParseIntPipe) Start: number,
    @Body() Data: GetDTO
): Promise<ResponseDTO> {
}

调试时,我可以看到它可以工作,因为它从 URL ( POST /25 )中获取 Start 参数,并将其添加到请求正文中,并用字符串“25”替换该值(或者如果它是则添加它不在请求正文中)。

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AddParametersToRequestBodyInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const req = context.switchToHttp().getRequest();
        const { params, body } = req; // get the params and body from req
        const NewRequestBody = { ...body, ...params }; // moves the params to the body, replacing matching data
        req.body = NewRequestBody; // just to be safe. I believe you could omit this, but rather safe than sorry
        return next.handle(); // keep the request going
    }
}

到目前为止,一切都很好。 ValidationPipe 是全局的,带有 whitelist: true 和 transform: true 选项。

ValidationPipeOptions = {
    transform: true,
    whitelist: true, // strip unknown fields
};

设置具有相同选项的本地 ValidationPipe 无济于事。 验证仍将 Start 视为字符串。

"Start must not be less than 1",
"Start must not be greater than 50",
"Start must be a number conforming to the specified constraints"

调试有效载荷显示:

Description: 'Testing',
Start: '25'

在请求正文中传递了描述,因此拦截器正在组合数据。

编辑我可以修改拦截器以确定正文中的字段是否为数字,例如:

intercept(context: ExecutionContext, next: CallHandler): Observable<any> 
{
    const req = context.switchToHttp().getRequest();
    const { params, body } = req; // get the params and body from req
    
    // Process through parameters checking values in request body
    for (const ParameterName in params) {
        if (typeof body[ParameterName] === 'number') {
            const Value: number = parseInt(params[ParameterName], 10);
            params[ParameterName] = Value;
        }
    }
    const NewRequestBody = { ...body, ...params }; // moves the params to the body
    req.body = NewRequestBody; // just to be safe. I believe you could omit this, but rather safe than sorry
    return next.handle(); // keep the request going
}

但是,这只适用于请求正文中的值。 我仍然需要确定如何将这些转换为使用 @Type(()=>Number) 进行验证

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM