Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 有没有办法将默认值设置为缺少/可选的JSON属性?_Node.js_Json_Typescript_Nestjs - Fatal编程技术网

Node.js 有没有办法将默认值设置为缺少/可选的JSON属性?

Node.js 有没有办法将默认值设置为缺少/可选的JSON属性?,node.js,json,typescript,nestjs,Node.js,Json,Typescript,Nestjs,我使用NodeJs/NestJs构建RESTful服务。我创建了一些与请求JSON匹配的对象。在这些对象中有一些可选属性,但是如果客户端不通过JSON发送它们,我想为它们设置默认值 实现目标的最佳方式是什么 这是我要与JSON匹配的DTO import { IsDefined, IsNumber, Min } from 'class-validator'; import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/sw

我使用NodeJs/NestJs构建RESTful服务。我创建了一些与请求JSON匹配的对象。在这些对象中有一些可选属性,但是如果客户端不通过JSON发送它们,我想为它们设置默认值

实现目标的最佳方式是什么

这是我要与JSON匹配的DTO

import { IsDefined, IsNumber, Min } from 'class-validator';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';

export class RequestDto {
    @IsDefined()
    @IsNumber()
    @Min(0)
    @ApiModelProperty({description: 'The current age.'})
    public CurrentAge: number;

    @ApiModelPropertyOptional({description: 'The existing saving amount.'})
    public ExistingSavingAmount: number = 0;
}
这是我的NestJs控制器

import { Controller, Post, Body, Param } from '@nestjs/common';
import { RequestDto } from './Dto/Request.Dto';
import { ApiResponse, ApiOperation } from '@nestjs/swagger';

@Controller('mycontroller')
export class MyController {
    @Post('MyEndPoint')
    @ApiOperation({ title: 'Do something' })
    @ApiResponse({ status: 201, description: 'Something is done' })
    public doSomething(@Body() request: RequestDto) {
        // do more jobs
    }
}
我启动服务,并将下面的JSON发布到我的终点

{
    "CurrentAge": 40,
}

在我的控制器中,我看到
ExistingSavingAmount
的值不是0而是空的。但是如果我直接实例化
RequestDto
,我可以看到
ExistingSavingAmount
的值是0。

好的,没有OP的代码样本,这个响应的保真度可能需要提高。也就是说,“nest-y”实现这一点的方法是通过

他们给出的典型示例是ParseIntPipe:

import { Injectable, BadRequestException} from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
在不知道默认值的情况下,我将假设它类似于一个产品,您希望默认一些内容,并将一些内容作为空字符串:

import { Injectable, BadRequestException} from '@nestjs/common';

// we will assume you have your own validation for the non-optional bits
const optionalDefaults = {
   description: '',
   category: 'Miscelleneous'
}

@Injectable()
export class ProductDefaultsPipe {
  transform(value, metadata) {
    const val = Object.assign(optionalDefaults, value);
    return val;
  }
}
现在,这意味着您可能正在使用提供模式和模型定义的东西(比如Joi或Mongoose)。如果是,那么我建议在该模式中设置所有默认值和验证,然后在TransformPipe中应用该模式,而不是编写大量自定义代码。例如,如果您有一个ProductSchema,这将适用于您:

@Injectable()
export class ProductDefaultsPipe {
  async transform(value, metadata) {
    const val = new Product(value);
    const isValid = await val.validate();
    if (!isValid) {
       throw new BadRequestException('Validation failed');
    }
    return val;
  }
}

只有当
RequestDto
实际实例化为类时,才会应用默认值。因为您已经在使用类验证器进行验证,所以可以使用
classTransformer.plainToClass()
来实例化该类

如果您使用的是内置的
ValidationPipe
,则可以使用
{transform:true}
选项来自动实例化
RequestDto
类:

@UsePipes(new ValidationPipe({ transform: true }))
@Post('MyEndPoint')
public doSomething(@Body() request: RequestDto) {
或作为全局管道:

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe({ transform: true }));
  await app.listen(3000);
}
bootstrap();

你能举一个你现有的端点为例吗,甚至可以用JSON示例来告诉我们你的意思吗?@Paul我已经用示例代码更新了我的帖子。非常感谢你的输入。进一步的问题是,如果不使用
classTransformer.plainToClass()
@usepippes(newvalidationpipe({transform:true}))
,DTO类就不会被实例化,那么它从何而来?由于我来自C#后台,因此在本例中,对象是从JSON反序列化的,因此它由序列化程序实例化。在这种情况下,JavaScript/TypeScript非常不同?如果没有类转换器,它将不会从JSON反序列化,而是保持一个普通的JavaScript对象。因为这发生在运行时,所以没有类型检查。事实上,在运行时您不会有RequestDto对象,而是会有一个普通对象(希望没有人检查)符合RequestDto的接口。