0

I've been trying to write Put (update) action without the id property, by using DTO. But every time I'm trying I'm getting the existing object and not the updated one, and I can't figure out why and how to change it so it will work.

My repository:

public User Update(Guid id, User user)
{
   var userToUpdate=_context.Users.FirstOrDefault(x => x.Id == id);
   _context.Entry(userToUpdate).State = EntityState.Modified;
   _context.SaveChanges();
   return userToUpdate;
}

My DTO:

public class UserPostDTO
{
    public UserPostDTO()
    {

    }
    public UserPostDTO(User user)
    {
        UserName= user.UserName;
        Password= user.Password;
        LastLogin= user.LastLogin;
    }
    [StringLength(255)]
    public string UserName { get; set; } = null!;
    [StringLength(255)]
    public string Password { get; set; } = null!;
    [Column(TypeName = "datetime")]
    public DateTime? LastLogin { get; set; }
    public User ToPostUser()
    {
        var user = new User();
        user.UserName = UserName;
        user.Password = Password;
        user.LastLogin = LastLogin;
        return user;
    }
}

My Controller:

public class UserController : ControllerBase
{
    private readonly IUserRepository _userRepository;
    public UserController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    [HttpPut("{id}")]
    public IActionResult Put(Guid id, [FromBody] UserPostDTO user)
    {
        _userRepository.Update(id, user.ToPostUser());
        return Ok();
    }
Yong Shun
  • 35,286
  • 4
  • 24
  • 46
Inbar Manor
  • 101
  • 1
  • 10

1 Answers1

1

Didn't see you updating the User object with the new value.

Probably this is what you need:

public User Update(Guid id, User user)
{
    var userToUpdate = _context.Users.FirstOrDefault(x => x.Id == id)
        .AsNoTracking();
    if (userToUpdate == null)
    {
        // Handle ID is not existed
        throw new ArgumentNullException("ID is not existed");
    }

    user.Id = userToUpdate.Id;
    _context.Entry(user).State = EntityState.Modified;
    _context.SaveChanges();
    return user;
}
Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • Thanks for your help, but It's not working well. but when I'm writing this code I'm getting this errpr: The instance of entity type 'User' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values. – Inbar Manor Jul 24 '22 at 07:00
  • 1
    Hmmm, the exception message is a bit broad, maybe you can try to remove the tracking graph from `userToUpdate` with `.AsNoTracking()` as it is used to validate whether the record is existed. This [post](https://stackoverflow.com/questions/48202403/instance-of-entity-type-cannot-be-tracked-because-another-instance-with-same-key) may help for solving your current issue. – Yong Shun Jul 24 '22 at 07:14