如何解决Angular表单插入.NET后端自增ID报错问题
解决自增列插入错误:Angular + .NET API 实战方案
问题根源
错误提示 Cannot insert explicit value for identity column in table 'StockFeed' when IDENTITY_INSERT is set to OFF,本质是SQL Server不允许手动给自增列赋值。
虽然Angular表单里没加Id字段,但你的.NET Stock模型包含Id属性,默认值为0。Angular在发送请求时会把这个0一起序列化到请求体中,.NET接收后,EF会尝试将这个0插入到自增的Id列,从而触发错误。
另外注意:你的Stock模型里有Production_date字段,但Angular表单未包含该控件,发送请求时这个字段会缺失,可能导致后端ModelState验证失败,需要同步处理。
推荐解决方案:使用DTO(数据传输对象)
这是前后端分离的标准做法,精确控制前端传入的字段,避免实体类直接暴露,提升安全性和可维护性。
步骤1:创建StockCreateDto类
在.NET项目中新建一个DTO类,只包含前端需要传入的字段:
namespace AuthAPI.Dtos { public class StockCreateDto { public long Company_id { get; set; } public long Stockfeedtype_id { get; set; } public int Installed_capacity { get; set; } public int Current_production { get; set; } public int Local_supply { get; set; } public int Exported { get; set; } public DateTime Production_date { get; set; } } }
步骤2:标记模型的自增属性
修改Stock模型,明确标记Id为数据库自增列:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace AuthAPI.Models { public class Stock { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标记为自增列 public int Id { get; set; } public long Company_id { get; set; } public long Stockfeedtype_id { get; set; } public int Installed_capacity { get; set; } public int Current_production { get; set; } public int Local_supply { get; set; } public int Exported { get; set; } public DateTime Production_date { get; set; } } }
步骤3:修改API控制器接收DTO
更新控制器代码,接收DTO并转换为实体类:
[HttpPost("addfeed")] public async Task<IActionResult> CreateStockFeed([FromBody] StockCreateDto stockFeedDto) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // 将DTO转换为Stock实体 var stockFeed = new Stock { Company_id = stockFeedDto.Company_id, Stockfeedtype_id = stockFeedDto.Stockfeedtype_id, Installed_capacity = stockFeedDto.Installed_capacity, Current_production = stockFeedDto.Current_production, Local_supply = stockFeedDto.Local_supply, Exported = stockFeedDto.Exported, Production_date = stockFeedDto.Production_date }; _dbContext.StockFeed.Add(stockFeed); await _dbContext.SaveChangesAsync(); return CreatedAtAction(nameof(GetStockFeedById), new { id = stockFeed.Id }, stockFeed); }
步骤4:补充Angular的Production_date字段
在Angular表单中添加日期控件,或在发送请求时自动生成日期:
// 修改组件的onInsert方法 onInsert() { if(this.stockFeedForm.valid){ const requestData = { ...this.stockFeedForm.value, production_date: new Date().toISOString() // 自动生成当前日期 }; this.auth.addfeed(requestData) .subscribe({ next:(res)=>{ alert(res.message); this.stockFeedForm.reset(); this.router.navigate(['stockFeed']); }, error:(err)=>{ alert(err.message); } }); }else{ validateForm.validateAllFormFields(this.stockFeedForm); alert("表单验证不通过"); } }
临时解决方案:Angular端手动移除Id字段
如果不想修改.NET端,可在发送请求前删除可能存在的Id字段:
onInsert() { if(this.stockFeedForm.valid){ const requestData = { ...this.stockFeedForm.value }; delete requestData.id; // 移除Id字段 requestData.production_date = new Date().toISOString(); this.auth.addfeed(requestData) .subscribe({ next:(res)=>{ alert(res.message); this.stockFeedForm.reset(); this.router.navigate(['stockFeed']); }, error:(err)=>{ alert(err.message); } }); }else{ validateForm.validateAllFormFields(this.stockFeedForm); alert("表单验证不通过"); } }
内容的提问来源于stack exchange,提问作者NewbieNerd
相关产品推荐
相关产品推荐

