ASP.NET API PUT方法如何仅更新提交对象的非空属性
实现ASP.NET API PUT部分更新(仅更新非空字段)的方案
方案1:手动逐个属性判断赋值(性能最优,适合属性少的场景)
该方案逻辑直观无额外开销,完全适配你当前的模型场景,同时建议把[FromQuery]改为[FromBody],PUT请求提交对象通常放在请求体中,可避免Query参数长度限制、参数泄露的问题。
完整接口代码如下:
[HttpPut] [Route("{id:int}")] public IActionResult Edit(int id, [FromBody] Questions question) { // 查询数据库中原有对象 Questions currentQuestion = _context.Questions.FirstOrDefault(x => x.QuestionId == id); if (currentQuestion == null) { return NotFound($"未找到ID为{id}的问题数据"); } // 仅非空属性赋值,空值属性保留原有数据 if (question.QuestionContent != null) { currentQuestion.QuestionContent = question.QuestionContent; } if (question.MediaUrl != null) { currentQuestion.MediaUrl = question.MediaUrl; } if (question.Description != null) { currentQuestion.Description = question.Description; } // 保存变更到数据库 _context.SaveChanges(); return Ok(currentQuestion); }
该方案可以直接实现你的需求:提交的参数中Description为null时不会覆盖数据库原有值,仅传了非空值的QuestionContent和MediaUrl会被更新。
方案2:反射实现通用部分更新(适合属性多、复用需求高的场景)
如果项目中多个模型都需要实现部分更新,可以封装通用扩展方法,避免重复写判空赋值逻辑:
public static class EntityUpdateExtension { /// <summary> /// 仅将源对象非空属性的值更新到目标对象 /// </summary> /// <typeparam name="T">实体类型</typeparam> /// <param name="target">数据库查询到的原有对象</param> /// <param name="source">前端提交的更新对象</param> public static void UpdateOnlyNonNullProps<T>(this T target, T source) { var properties = typeof(T).GetProperties() // 过滤主键属性,避免主键被意外修改 .Where(p => p.Name != nameof(Questions.QuestionId) && p.CanWrite); foreach (var prop in properties) { var sourceValue = prop.GetValue(source); if (sourceValue != null) { prop.SetValue(target, sourceValue); } } } }
在接口中直接调用扩展方法即可,代码大幅简化:
[HttpPut] [Route("{id:int}")] public IActionResult Edit(int id, [FromBody] Questions question) { Questions currentQuestion = _context.Questions.FirstOrDefault(x => x.QuestionId == id); if (currentQuestion == null) { return NotFound($"未找到ID为{id}的问题数据"); } // 调用扩展方法批量更新非空属性 currentQuestion.UpdateOnlyNonNullProps(question); _context.SaveChanges(); return Ok(currentQuestion); }
注意事项
- 如果模型包含值类型属性(如int、DateTime等),需要声明为可空类型(如int?、DateTime?),否则值类型默认值(比如int的0)会被误认为是有意提交的更新值,导致逻辑错误。
- 如果需要支持将某个字段主动更新为null,可以额外加参数标记需要置空的字段,或者单独写对应逻辑处理。
内容的提问来源于stack exchange,提问作者Adam Wróbel
相关产品推荐
相关产品推荐

