ASP.NET Core 7 Web API日期序列化适配Angular表单控件问题
无需手动转换让Angular自动识别Date类型的方案
方案1:全局HTTP拦截器统一转换日期
实现一个HTTP拦截器,拦截所有接口响应,自动将符合ISO 8601格式的字符串转为Date类型,全局生效无需逐个请求处理。
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() export class DateInterceptor implements HttpInterceptor { private isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/; intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { return next.handle(request).pipe( map(event => { if (event instanceof HttpResponse) { return event.clone({ body: this.convertDates(event.body) }); } return event; }) ); } private convertDates(body: any): any { if (body === null || body === undefined || typeof body !== 'object') { return body; } for (const key of Object.keys(body)) { const value = body[key]; if (typeof value === 'string' && this.isoDateRegex.test(value)) { body[key] = new Date(value); } else if (typeof value === 'object') { this.convertDates(value); } } return body; } }
在AppModule中注册拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { DateInterceptor } from './date.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: DateInterceptor, multi: true } ] }) export class AppModule { }
方案2:配置HttpClient的自定义JSON解析器
修改HttpClient默认的JSON解析逻辑,在解析响应时自动转换日期字符串。
import { HttpClient, HttpBackend } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() export class CustomHttpClient extends HttpClient { constructor(handler: HttpBackend) { super(handler); } override get<T>(url: string): Observable<T> { return super.get(url, { responseType: 'text' as 'json' }).pipe( map(response => this.parseJsonWithDates(response as string) as T) ); } private parseJsonWithDates(jsonString: string): any { const isoDateRegex = /(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?)/g; return JSON.parse(jsonString, (key, value) => { if (typeof value === 'string' && isoDateRegex.test(value)) { return new Date(value); } return value; }); } }
在AppModule中替换默认HttpClient:
import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; import { CustomHttpClient } from './custom-http-client'; @NgModule({ imports: [HttpClientModule], providers: [ { provide: HttpClient, useClass: CustomHttpClient } ] }) export class AppModule { }
方案3:利用类构造函数转换
在Angular的Person类中添加构造函数,接收后端数据时自动转换日期字段。
export class Person { name: string; birthday: Date; constructor(data: Partial<Person>) { Object.assign(this, data); if (typeof data.birthday === 'string') { this.birthday = new Date(data.birthday); } } }
请求时映射为Person实例:
this.httpClient.get<any>(url).pipe( take(1), map(data => new Person(data)) ).subscribe({ next: (result: Person) => { console.log('result.birthday 已转为Date类型:', result.birthday instanceof Date); } });
方案4:ASP.NET Core端返回时间戳(可选)
修改后端JSON序列化规则,将DateTime转为Unix时间戳,Angular可直接基于数字生成Date。此方案会改变接口返回格式,需考虑兼容性。
在ASP.NET Core的Program.cs中配置:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new DateTimeToTimestampConverter()); }); // 自定义时间戳转换器 public class DateTimeToTimestampConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return DateTimeOffset.FromUnixTimeMilliseconds(reader.GetInt64()).UtcDateTime; } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { writer.WriteNumberValue(new DateTimeOffset(value.ToUniversalTime()).ToUnixTimeMilliseconds()); } }
内容的提问来源于stack exchange,提问作者FunkMonkey33
相关产品推荐
相关产品推荐

