Web Api反序列化Angular提交对象遇Error reading object reference '1'问题
嘿,我之前也碰到过类似的坑,咱们一步步拆解这个问题:
首先,这个错误提示Error reading object reference '1'本质上是反序列化器把你提交的数字1当成了对象引用标识,而不是DeveloperId的属性值——这大概率和序列化配置或者实体类的映射有关,毕竟你说Stakeholders能正常工作,说明基础流程是通的。
下面是几个你可以排查的方向:
1. 检查Web API的全局反序列化配置
如果你用的是Newtonsoft.Json(ASP.NET Core早期默认用这个,错误提示风格也更匹配),看看有没有全局开启了PreserveReferencesHandling:
// 比如在Startup.cs/Program.cs里的配置 services.AddControllers() .AddNewtonsoftJson(options => { // 如果开启了这个,反序列化器会把数字当成对象引用的$id,而不是属性值 // 把它改成None或者直接注释掉 options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None; // 顺便加上循环引用处理,避免双向关联的问题 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
这个配置是最常见的诱因——如果Stakeholder类刚好没有触发引用逻辑,而Developer类因为导航属性触发了,就会出现一边正常一边报错的情况。
2. 检查Developer类的注解和结构
虽然你说它和Stakeholder结构类似,但还是仔细核对下:
public class Developer { // 确认这里没有误加奇怪的注解,比如[JsonReference]或者错误的[ForeignKey] public int DeveloperId { get; set; } public string Name { get; set; } // 如果有和Application的双向导航属性,比如下面这个 // 要么加[JsonIgnore]让序列化器忽略它,要么在配置里开ReferenceLoopHandling.Ignore // [JsonIgnore] // public Application Application { get; set; } }
有没有可能你给Developer的导航属性加了特殊注解,导致序列化器把DeveloperId当成了引用的外键标识?
3. 核对Angular提交的JSON细节
虽然你说JSON是有效的,但看看Developers数组里的对象和Stakeholders的差异:
比如Stakeholders的结构是
{"StakeholderId": 2, ...},而Developers是不是不小心写成了{"$ref": "1"}?(如果之前开启过引用序列化,Angular可能缓存了旧格式)
如果是纯数字的"DeveloperId": 1,那问题肯定在API端的配置;如果是带$ref的格式,那要么改Angular的提交格式,要么API端开启对应的引用处理。
4. 临时测试:手动反序列化排查
你可以在API的Action里先把请求体读成字符串,然后手动反序列化测试,看看是不是全局配置的问题:
[HttpPost] public IActionResult SubmitApplication() { using var reader = new StreamReader(Request.Body); var json = reader.ReadToEnd(); // 用默认配置手动反序列化 var settings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; try { var app = JsonConvert.DeserializeObject<Application>(json, settings); return Ok(app); } catch (Exception ex) { return BadRequest(ex.Message); } }
如果手动反序列化成功,那就是全局配置的问题,调整全局设置即可。
内容的提问来源于stack exchange,提问作者Joseph

