.NET Core Web API接收Angular表单数据为Null且后续失效问题排查
你遇到的问题是由Angular表单拼写错误、请求序列化逻辑不当,再加上.NET API的数据库配置问题共同导致的,下面一步步拆解解决:
1. 修复Angular模板的核心拼写错误
这是最关键的问题!你的模板里把formControlName写成了formComtrolName(少了字母r),导致表单控件完全没和FormGroup绑定,提交的表单值自然全是null。
修改模板里所有的formComtrolName为formControlName,同时确保字段名和你FormGroup里定义的完全一致(大小写敏感):
<div class="add-customer"> <form [formGroup]="addCustomerForm" (ngSubmit)="onSubmit()"> <div class="form-group"> <label for="versionid" class="required">Id</label> <input type="number" class="form-control" id="versionId" formControlName="VersionId" placeholder="Version Id "> </div> <div class="form-group"> <label for="name" class="required">HR Portail</label> <input type="text" class="form-control" id="name" formControlName="Name" placeholder="Url"> </div> <div class="form-group"> <label for="url" class="required">Job Portail</label> <input type="text" class="form-control" id="url" formControlName="Url" placeholder="Url"> </div> <div class="form-group"> <label for="dns" class="required">DNS</label> <input type="text" class="form-control" id="dns" formControlName="Dns" placeholder="dns"> </div> <button class="btn btn-success" type="submit">Add</button> <button class="btn btn-default" [routerLink]="['/customers']">Cancel</button> </form> </div>
2. 简化Angular服务的请求逻辑
HttpClient会自动帮你序列化对象并设置正确的请求头,手动JSON.stringify反而容易出错,而且你代码里的headers变量根本没定义,会导致请求头缺失。
修改CustomerService的addCustomer方法:
import { HttpHeaders } from '@angular/common/http'; export class CustomerService { _baseURL: string = "api/customers"; // 定义正确的JSON请求头 private headers = new HttpHeaders({ 'Content-Type': 'application/json' }); constructor(private http: HttpClient) { } getAllCustomers(){ return this.http.get<Customer[]>(`${this._baseURL}/getcustomers`); } addCustomer(customer: Customer){ // 直接传对象,HttpClient会自动处理序列化 return this.http.post<Customer>(`${this._baseURL}/addcustomer`, customer, { headers: this.headers }); } }
另外,确保你的Customer接口字段和.NET模型的字段匹配(.NET Core默认支持驼峰命名的请求体绑定,所以Angular用驼峰versionId也能映射到.NET的VersionId)。
3. 配置.NET API的Customer模型自增主键
你的Customer模型里Id是public int Id { get; set; }(非可空),但Angular表单没提交Id字段。如果数据库里Id是自增主键,必须在模型上配置,否则插入时会因为Id为0导致主键冲突(这大概率是插入Null记录后API失效的原因)。
在Customer模型的Id属性上添加特性:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; public partial class Customer { public Customer() { Pack = new HashSet<Pack>(); } [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标记为自增主键 public int Id { get; set; } // 其他属性... public int? VersionId { get; set; } public string Name { get; set; } public string Url { get; set; } public string Dns { get; set; } // 剩余属性... }
或者在DbContext的OnModelCreating方法里配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Customer>() .Property(c => c.Id) .ValueGeneratedOnAdd(); }
4. 验证API的模型绑定(可选调试步骤)
你可以在AddCustomer方法里添加调试代码,确认是否正确接收到请求体:
using System.Text.Json; [HttpPost("AddCustomer")] public IActionResult AddCustomer([FromBody]Customer customer) { // 调试用:打印接收到的对象 Console.WriteLine(JsonSerializer.Serialize(customer)); if (!ModelState.IsValid) return BadRequest(ModelState); using (var context = new HrmapsMasterContext()) { context.Customer.Add(customer); context.SaveChanges(); return Ok(); } }
如果还是接收不到值,检查Program.cs里的JSON序列化配置,确保支持驼峰命名:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; });
最后一步:清理无效记录并测试
先删除数据库里那条全Null的无效记录,然后按上面的步骤修改代码,重新测试:
- 在Angular表单输入值提交,查看数据库是否生成正确记录
- 用Postman再次调用API,确认功能恢复正常
内容的提问来源于stack exchange,提问作者IHEB

