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

如何仅更新传入ViewModel中的指定字段而不将未传字段置空

问题根因

默认情况下,.NET 模型绑定处理API请求时,如果请求报文中没有包含ViewModel对应属性的参数,会自动给该属性赋值为对应类型的默认值,string类型的默认值就是null。如果你直接把绑定后的ViewModel全量覆盖到数据库实体上,就会导致未传参的字段被覆盖为null。

可行解决方案
  • 方案1:使用JSON Patch实现局部更新(官方推荐,适用所有局部更新场景,支持显式将字段设为null的需求)

    1. 安装依赖包Microsoft.AspNetCore.Mvc.NewtonsoftJson,JSON Patch依赖Newtonsoft.Json实现
    2. Program.cs中注册NewtonsoftJson支持:
    builder.Services.AddControllers().AddNewtonsoftJson();
    
    1. 接口参数改为JsonPatchDocument类型:
    public async Task<IActionResult> UpdateUser(int id, [FromBody] JsonPatchDocument<UserUpdateViewModel> patchDoc)
    {
        // 先查询原有实体
        var user = await _context.Users.FindAsync(id);
        if (user == null) return NotFound();
        
        // 应用Patch变更,仅更新传入的字段
        patchDoc.ApplyTo(user);
        await _context.SaveChangesAsync();
        return Ok();
    }
    

    对应的请求格式需要改为PATCH类型,报文示例:

    [
      {
        "op": "replace",
        "path": "/name",
        "value": "my name"
      }
    ]
    
  • 方案2:手动判断非null字段再赋值(简单易用,适用字段较少的场景)
    先查询数据库中的原有实体,仅将ViewModel中不为null的字段赋值到实体上:

    var existingUser = await _context.Users.FindAsync(id);
    if (existingUser == null) return NotFound();
    
    // 仅更新非null字段
    if (viewModel.Name != null) existingUser.Name = viewModel.Name;
    if (viewModel.Email != null) existingUser.Email = viewModel.Email;
    if (viewModel.Phone != null) existingUser.Phone = viewModel.Phone;
    
    await _context.SaveChangesAsync();
    

    注意:如果业务支持将字段主动设置为null,此方案会失效,推荐用方案1

  • 方案3:使用AutoMapper条件映射(适用字段较多的场景,减少重复代码)
    配置AutoMapper映射规则时,指定仅当源属性不为null时才执行映射:

    CreateMap<UserUpdateViewModel, User>()
        .ForAllMembers(opts => opts.Condition((src, dest, srcValue) => srcValue != null));
    

    映射时直接使用原有实体作为映射目标即可:

    _mapper.Map(viewModel, existingUser);
    

内容的提问来源于stack exchange,提问作者Fachrul Rozi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:45:04