Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.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
使用NestJS和类验证器创建头自定义验证_Nestjs_Class Validator - Fatal编程技术网

使用NestJS和类验证器创建头自定义验证

使用NestJS和类验证器创建头自定义验证,nestjs,class-validator,Nestjs,Class Validator,我一直在使用类验证器验证请求,NestJS validation plus尝试验证头内容。我的基本接口都正常工作,但现在我正试图以相同的方式比较一些标题字段数据 我试图处理标题,但是这个问题的解决方案将返回一个标题。我希望能够处理所有这些数据,就像处理所有body()数据一样 我需要能够创建一个用于提取头字段的自定义装饰器,并能够将它们传递到类验证器DTO中 例如,我想验证三个标题字段,例如: User-Agent = 'Our Client Apps' Content-Type = 'appl

我一直在使用类验证器验证请求,NestJS validation plus尝试验证头内容。我的基本接口都正常工作,但现在我正试图以相同的方式比较一些标题字段数据

我试图处理标题,但是这个问题的解决方案将返回一个标题。我希望能够处理所有这些数据,就像处理所有body()数据一样

我需要能够创建一个用于提取头字段的自定义装饰器,并能够将它们传递到类验证器DTO中

例如,我想验证三个标题字段,例如:

User-Agent = 'Our Client Apps'
Content-Type = 'application/json'
traceabilityId = uuid
还有更多的领域,但如果我能做到这一点,那么我可以推断出其余的领域。我有一个简单的控制器示例:

@Controller(/rest/package)
export class PackageController {

    constructor(
        private PackageData_:PackageService
    )
    { }

    ...

    @Post('inquiry')
    @HttpCode(HttpStatus.OK)        // Not creating data, but need body, so return 200 OK
    async StatusInquiry(
        @RequestHeader() HeaderInfo:HeadersDTO,     // This should be the Headers validation using the decorator from the question above.
我正在尝试验证请求的头是否包含一些特定的数据,我正在使用NestJS。我找到了这个。虽然这是我想要做的,而且看起来很合适,但是类类型引用不存在,我不确定应该使用什么来代替

从这个例子中,装饰者指的是

request-header.decorator.ts

export interface iError {
    statusCode:number;
    messages:string[];
    error:string;
}

export const RequestHeader = createParamDecorator(
async (value:  any, ctx: ExecutionContext) => {

    // extract headers
    const headers = ctx.switchToHttp().getRequest().headers;

    // Convert headers to DTO object
    const dto = plainToClass(value, headers, { excludeExtraneousValues: true });

    // Validate
    const errors: ValidationError[] = await validate(dto);

    if (errors.length > 0) {
        let ErrorInfo:IError = {
            statusCode: HttpStatus.BAD_REQUEST,
            error: 'Bad Request',
            message: new Array<string>()
        };
        
        errors.map(obj => { 
            AllErrors = Object.values(obj.constraints);    
            AllErrors.forEach( (OneError) => {
            OneError.forEach( (Key) => {
                ErrorInfo.message.push(Key);
            });
        });

    // Your example, but wanted to return closer to how the body looks, for common error parsing
    //Get the errors and push to custom array
    // let validationErrors = errors.map(obj => Object.values(obj.constraints));
    throw new HttpException(`${ErrorInfo}`, HttpStatus.BAD_REQUEST);
}

// return header dto object
return dto;
通过邮递员发送请求的邮件头:

Content-Type:application/json
operationMode:PRODUCTION
Accept-Language:en
如中所述,您需要创建一个DTO类并将其传递给
RequestHeader
decorator

e、 g


我刚刚测试了以下代码,这是可行的。我想你在这里找不到合适的类型

async StatusInquiry(
    @RequestHeader() HeaderInfo:HeadersDTO,
您应该将HeadersDTO作为参数传入RequestHeader装饰器此
@RequestHeader(HeadersDTO)HeaderInfo:HeadersDTO,

然后我创建了customDecorator.ts,如下所示

export const RequestHeader = createParamDecorator(
//Removed ClassType<unknown>,, I don't think you need this here
async (value:  any, ctx: ExecutionContext) => {

    // extract headers
    const headers = ctx.switchToHttp().getRequest().headers;

    // Convert headers to DTO object
    const dto = plainToClass(value, headers, { excludeExtraneousValues: true });

    // Validate
    const errors: ValidationError[] = await validate(dto);
    
    if (errors.length > 0) {
        //Get the errors and push to custom array
        let validationErrors = errors.map(obj => Object.values(obj.constraints));
        throw new HttpException(`Validation failed with following Errors: ${validationErrors}`, HttpStatus.BAD_REQUEST);
    }

    // return header dto object
    return dto;
},
class HeadersDTO {
}
tslib_1.__decorate([
    class_validator_1.IsDefined(),
    class_transformer_1.Expose({ name: 'custom-header' }),
    tslib_1.__metadata("design:type", String)
], HeadersDTO.prototype, "custom-header", void 0);
exports.HeadersDTO = HeadersDTO;
我在查看编译的TS文件时发现的原因是

export const RequestHeader = createParamDecorator(
//Removed ClassType<unknown>,, I don't think you need this here
async (value:  any, ctx: ExecutionContext) => {

    // extract headers
    const headers = ctx.switchToHttp().getRequest().headers;

    // Convert headers to DTO object
    const dto = plainToClass(value, headers, { excludeExtraneousValues: true });

    // Validate
    const errors: ValidationError[] = await validate(dto);
    
    if (errors.length > 0) {
        //Get the errors and push to custom array
        let validationErrors = errors.map(obj => Object.values(obj.constraints));
        throw new HttpException(`Validation failed with following Errors: ${validationErrors}`, HttpStatus.BAD_REQUEST);
    }

    // return header dto object
    return dto;
},
class HeadersDTO {
}
tslib_1.__decorate([
    class_validator_1.IsDefined(),
    class_transformer_1.Expose({ name: 'custom-header' }),
    tslib_1.__metadata("design:type", String)
], HeadersDTO.prototype, "custom-header", void 0);
exports.HeadersDTO = HeadersDTO;
当我没有通过标题时,会出现以下错误

[
  ValidationError {
    target: HeadersDTO { 'custom-header': undefined },
    value: undefined,
    property: 'custom-header',
    children: [],
    constraints: { isDefined: 'custom-header should not be null or undefined' }
  }
]

我这样做,正如你在控制器中看到的。但是,我没有发送标题,也没有失败。另外,在request-headers.decorator.ts中,该代码不会运行,因为类类型未定义。返回标题的答案不会调用验证,这仍然是我的主要问题。@StevenScott在您的示例中,如果您执行
@RequestHeader()HeaderInfo:HeadersDTO
,则应该是
@RequestHeader(HeadersDTO)headers:HeadersDTO
,我添加了
@RequestHeader(HeadersDTO)headers:HeadersDTO
,但这不会导致故障发生。例如,使用Postman发布请求,我禁用了发送用户代理。我的代码检查它是否是我们的客户。我用示例DTO更新了这个问题。我相信您遵循了这个链接-。如果是,请交叉检查是否丢失了任何内容是,除了未找到类类型的问题仍然存在外,它将不会编译<代码>从'ClassTransformer/ClassTransformer'导入{ClassType}错误是
找不到模块'class transformer/ClassTransformer'或其相应的类型声明。ts(2307)
我已经测试了下面我发布的代码,它正在为meSorry工作,没有看到您将类类型更改为简单的any。这确实给了我一个服务器错误,现在是500,而不是正常的400错误请求。有没有一种方法可以让默认处理生效?您可以添加自定义验证并抛出异常
await validateorject(dto)函数。我做了同样的事情,还注意到我现在使用了
validate(obj)
方法。更新的回答确实解决了问题,我可以重新格式化这些。我希望得到一致性的内部调用,但是可以处理这个问题。但是我没有得到传入的头值。因此,当验证运行时,它不是真正的验证,因为引号中的标题字段没有填充,因此它们的值未定义。我能够看到我传递的标题值。。。我只是监视他们,可以看到。您是说无法获取标题值吗?您在哪里尝试访问这些值?
[
  ValidationError {
    target: HeadersDTO { 'custom-header': undefined },
    value: undefined,
    property: 'custom-header',
    children: [],
    constraints: { isDefined: 'custom-header should not be null or undefined' }
  }
]