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

ASP.NET Core Web API使用DTO的Put接口未更新对象问题

问题分析与解决方案

你的Put接口调用后始终返回原对象,核心原因是仓库的Update方法没有将DTO中的更新值同步到数据库查询出的实体上。当前代码仅标记实体为Modified状态,但实体的属性值仍为原始值,导致SaveChanges执行后数据库无更新。

1. 修复仓库Update方法

修改仓库代码,将DTO转换来的User对象的属性值赋值给查询到的数据库实体,再执行保存:

public User Update(Guid id, User user)
{
    var userToUpdate = _context.Users.FirstOrDefault(x => x.Id == id);
    if (userToUpdate == null)
    {
        // 根据业务需求,可返回null或抛出异常
        return null;
    }
    // 同步更新属性值
    userToUpdate.UserName = user.UserName;
    userToUpdate.Password = user.Password;
    userToUpdate.LastLogin = user.LastLogin;
    
    // EF Core会自动追踪实体变更,无需手动设置Modified状态(除非实体处于断开追踪状态)
    // _context.Entry(userToUpdate).State = EntityState.Modified;
    _context.SaveChanges();
    return userToUpdate;
}

2. 优化DTO与实体的交互(可选)

在DTO中添加更新实体的方法,避免在仓库中硬编码属性赋值:

public class UserPostDTO
{
    // 原有构造函数、属性保持不变...

    // 新增更新实体的方法
    public void ApplyToUser(User user)
    {
        user.UserName = this.UserName;
        user.Password = this.Password;
        user.LastLogin = this.LastLogin;
    }
}

对应控制器和仓库可调整为:

控制器代码

[HttpPut("{id}")]
public IActionResult Put(Guid id, [FromBody] UserPostDTO userDto)
{
    var userToUpdate = _userRepository.GetById(id);
    if (userToUpdate == null)
    {
        return NotFound();
    }
    userDto.ApplyToUser(userToUpdate);
    _userRepository.SaveChanges();
    return Ok(userToUpdate);
}

仓库补充方法

public User GetById(Guid id)
{
    return _context.Users.FirstOrDefault(x => x.Id == id);
}

public void SaveChanges()
{
    _context.SaveChanges();
}

3. 额外注意事项

  • 必须添加实体null检查,避免空引用异常,同时返回合适的HTTP状态码(如NotFound)。
  • EF Core中,被上下文追踪的实体修改属性后,SaveChanges会自动识别变更并更新数据库,无需手动设置EntityState.Modified。
  • 若项目中频繁涉及DTO与实体的映射,可使用AutoMapper等工具简化代码,减少手动赋值的出错概率。

内容的提问来源于stack exchange,提问作者Inbar Manor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:06:25