You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 14:24:03