如何在带有 HTML 渲染的 NestJs 中使用验证?

Posted

技术标签:

【中文标题】如何在带有 HTML 渲染的 NestJs 中使用验证?【英文标题】:How to use validation in NestJs with HTML rendering? 【发布时间】:2019-07-28 07:39:54 【问题描述】:

NestJS 使用验证管道和验证

@UsePipes(ValidationPipe)

如果失败,则会引发异常。这对于返回 JSON 的 REST API 来说很好。

在使用 html 渲染时如何验证参数并返回

 errors: ['First error'] 

到 hbs 模板?

【问题讨论】:

您是否有一个单独的 hbs 错误模板要在错误时呈现,或者是否应该在路由的 hbs 模板中呈现错误? 错误应该在 hbs 模板中呈现(在表单中)。 【参考方案1】:

您可以创建一个Interceptor,将验证错误转换为错误响应:

@Injectable()
export class ErrorsInterceptor implements NestInterceptor 
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> 
    return call$.pipe(
        // Here you can map (or rethrow) errors
        catchError(err => (errors: [err.message]),
      ),
    );
  

您可以通过将@UseInterceptors(ErrorsInterceptor) 添加到您的控制器或其方法来使用它。

【讨论】:

【参考方案2】:

我一直在让自己发疯,试图找到一种“类似嵌套”的方式来做到这一点,同时仍然保持一定程度的可定制性,我想我终于做到了。首先,我们想要一个引用现有 class-validator 错误的错误,因此我们创建一个自定义错误类,如下所示:

import  ValidationError  from 'class-validator';

export class ValidationFailedError extends Error 
  validationErrors: ValidationError[];
  target: any;

  constructor(validationErrors) 
    super();
    this.validationErrors = validationErrors;
    this.target = validationErrors[0].target
  


(我们还有一个对我们尝试验证的类的引用,因此我们可以适当地返回我们的对象)

然后,在main.ts 中,我们可以像这样设置自定义异常工厂:

  app.useGlobalPipes(
    new ValidationPipe(
      exceptionFactory: (validationErrors: ValidationError[] = []) => 
        return new ValidationFailedError(validationErrors);
      ,
    ),
  );

接下来,我们创建一个ExceptionFilter 来捕获我们的自定义错误,如下所示:


@Catch(ValidationFailedError)
export class ValidationExceptionFilter implements ExceptionFilter 
  view: string
  objectName: string

  constructor(view: string, objectName: string) 
    this.view = view;
    this.objectName = objectName;
  

  async catch(exception: ValidationFailedError, host: ArgumentsHost) 
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    response.render(this.view, 
      errors: exception.validationErrors,
      [this.objectName]: exception.target,
      url: request.url,
    );
  

我们还添加了一个初始化器,因此我们可以指定要渲染的视图和对象的名称,因此我们可以像这样在控制器方法上设置我们的过滤器:

  @Post(':postID')
  @UseFilters(new ValidationExceptionFilter('blog-posts/edit', 'blogPost'))
  @Redirect('/blog-posts', 301)
  async update(
    @Param('id') postID: string,
    @Body() editBlogPostDto: EditBlogPostDto,
  ) 
    await this.blogPostsService.update(postID, editBlogPostDto);
  

希望这对某些人有所帮助,因为我喜欢 NestJS,但与更传统的全栈 CRUD 应用程序相比,文档和教程似乎更适合 JSON API。

【讨论】:

以上是关于如何在带有 HTML 渲染的 NestJs 中使用验证?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 neo4j-graphql-js 端点中使用带有 nestjs 框架的拦截器?

带有实体关系的nestjs graphql - 如何装饰它?

如何在客户端中使用 Firebase Auth gmail 保护 NestJS 中的 API?

如何在 NestjS 中使用可选的 url 参数

NestJS 在非模块文件中注入模块服务

NestJS-Prisma 如何使用关系字段创建记录?