ASP.NET Core Web API中EF Core 5返回特殊格式对象导致Angular表格无法渲染的问题排查
这个问题我之前也碰到过,咱们一步步来分析解决:
为什么会出现这种格式?
这是因为你的ASP.NET Core Web API在序列化EF Core实体时,启用了**引用保留(PreserveReferencesHandling)**功能。通常是为了处理实体间的循环引用(比如导航属性互相引用)才开启的。当使用Newtonsoft.Json(旧版ASP.NET Core默认序列化器)并配置了PreserveReferencesHandling.Objects时,EF Core会把数组序列化为包含$id(用于标识唯一对象)和$values(实际的数组内容)的包装对象,而不是直接返回纯数组,这就导致Angular无法识别为普通数组进行遍历。
解决方案
方案1:修改API序列化配置(推荐)
如果你的实体没有循环引用问题,或者可以用其他方式处理循环引用,直接关闭引用保留配置就能让API返回纯数组,Angular代码无需改动。
在ASP.NET Core的Program.cs(.NET 6+)或者Startup.cs(旧版本)中修改Json序列化设置:
// .NET 6+ Program.cs示例 builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 关闭引用保留,禁用$id/$values包装 options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None; // 如果存在循环引用,用Ignore替代保留引用,避免序列化报错 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
如果你的API用的是System.Text.Json(ASP.NET Core 3.0+默认),且手动配置了ReferenceHandler.Preserve,可以改为:
builder.Services.AddControllers() .AddJsonOptions(options => { // 忽略循环引用,同时不生成$id包装 options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; });
方案2:在Angular端适配返回格式
如果暂时无法修改API,可以在Angular服务里手动提取$values部分的数据:
修改服务中的getOfertas方法:
getOfertas(): Observable<Oferta[]> { return this.http.get<any>(`${this.urlWebAPI}/ofertas`) .pipe( // 提取响应中的$values数组作为实际数据 map(response => response.$values as Oferta[]), tap(data=>console.log('OfertasService-get(): ', data) ), catchError(this.handleError) ) }
同时,组件HTML里的遍历要改成直接用ofertas(不再需要. $values),另外注意你之前的HTML里有几列错误绑定了oferta.id,比如Organismo和Presupuesto列,记得修正为对应的字段:
<tr *ngFor="let oferta of ofertas; let index=index"> <td>{{oferta.id}}</td> <td>{{oferta.idPresentada}}</td> <td>{{oferta.descripcion}}</td> <td>{{oferta.organismo}}</td> <td>{{oferta.fechaPresentacionFulcrum}}</td> <td>{{oferta.presupuesto}}</td> </tr>
内容的提问来源于stack exchange,提问作者kintela

