You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何解析.NET Web API返回的ProblemDetails类型错误信息?

在Angular中解析.NET Web API验证错误信息

1. 定义TypeScript类型(实现类型安全)

先定义对应ProblemResponse的接口,方便后续代码的类型推导:

interface ProblemDetails {
  type?: string;
  title?: string;
  status?: number;
  traceId?: string;
  errors?: Record<string, string[]>;
}

2. 编写错误解析工具函数

实现一个函数,将返回的errors对象转换为「字段名: 错误信息」格式的字符串数组,同时处理空字段名的情况:

parseValidationErrors(errors: Record<string, string[]> | undefined): string[] {
  if (!errors) return [];

  const errorMessages: string[] = [];
  
  Object.entries(errors).forEach(([field, messages]) => {
    // 空字段名替换为友好提示,比如"请求内容"
    const displayField = field || "请求内容";
    messages.forEach(message => {
      errorMessages.push(`${displayField}: ${message}`);
    });
  });

  return errorMessages;
}

3. 在HTTP错误处理中解析并展示错误

可以通过HTTP拦截器全局处理所有400错误,或者在单个请求的错误回调中针对性处理:

方式一:用HTTP拦截器全局处理

创建拦截器统一捕获400错误,解析后调用toast组件展示:

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
import { Observable, catchError } from 'rxjs';
import { ToastService } from './toast.service'; // 假设你已实现Toast提示服务

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

  constructor(private toastService: ToastService) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 400 && error.error?.errors) {
          const problemDetails = error.error as ProblemDetails;
          const errorMessages = this.parseValidationErrors(problemDetails.errors);
          // 逐个展示错误提示
          errorMessages.forEach(msg => this.toastService.showError(msg));
          // 也可以合并成一个字符串展示:errorMessages.join('\n')
        }
        throw error; // 继续抛出错误,供后续业务逻辑处理
      })
    );
  }

  private parseValidationErrors(errors: Record<string, string[]> | undefined): string[] {
    if (!errors) return [];
    const errorMessages: string[] = [];
    Object.entries(errors).forEach(([field, messages]) => {
      const displayField = field || "请求内容";
      messages.forEach(message => {
        errorMessages.push(`${displayField}: ${message}`);
      });
    });
    return errorMessages;
  }
}

然后在AppModule中注册拦截器:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './error.interceptor';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

方式二:单个请求中处理错误

如果不需要全局处理,也可以在具体请求的错误回调中解析:

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ToastService } from './toast.service';

constructor(private http: HttpClient, private toastService: ToastService) {}

submitForm(data: any) {
  this.http.post('/api/your-endpoint', data).subscribe({
    next: (res) => {
      // 处理成功逻辑
    },
    error: (error: HttpErrorResponse) => {
      if (error.status === 400 && error.error?.errors) {
        const problemDetails = error.error as ProblemDetails;
        const errorMessages = this.parseValidationErrors(problemDetails.errors);
        errorMessages.forEach(msg => this.toastService.showError(msg));
      }
    }
  });
}

private parseValidationErrors(errors: Record<string, string[]> | undefined): string[] {
  // 同上述解析函数
}

内容的提问来源于stack exchange,提问作者Saurabh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:25:30