Josh Kautz
Josh Kautz

Reputation: 609

EF Core 3.1 is overwriting all of the fields with null values from DTO when I send an HTTP PUT update request to my API

Context

I have an API set up with CRUD operations - I am having trouble with the HTTP PUT endpoint that I use for updating an entity. I only want the API to be able to update some fields for the entity, so I use a Data transfer object (DTO), and use AutoMapper to map it to the domain model for Entity Framework Core (EF Core) to update the entity in the database. When using AutoMapper to map from the DTO to the domain model, null values will be added, and then overwrite these values in the database. How can I prevent this from happening?

Code

PlayerController.cs

[HttpPut("{id}")]
public async Task<IActionResult> PutPlayer(Guid id, PlayerUpdateDto playerUpdateDto)
{
    Player player = _mapper.Map<Player>(playerUpdateDto);

    _context.Entry(player).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!PlayerExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return Ok(player);
}

Player.cs

public class Player
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public string Name { get; set; }

    public double Rating { get; set; }

    public DateTime Created { get; set; }
    public DateTime Updated { get; set; }

    public ICollection<Match> MatchesOne { get; set; }
    public ICollection<Match> MatchesTwo { get; set; }
    public ICollection<Match> MatchesThree { get; set; }
    public ICollection<Match> MatchesFour { get; set; }
}

PlayerUpdateDto.cs

public class PlayerUpdateDto
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

The Player rating, created, and updated properties all get set to null values, but I want them to remain the same since they're not in the DTO. Any and all help would be greatly appreciated!

Upvotes: 1

Views: 1766

Answers (1)

David Browne - Microsoft
David Browne - Microsoft

Reputation: 89386

This

 _context.Entry(player).State = EntityState.Modified;

Marks all the properties as modified. Instead mark only the ones you want to update. Eg

 _context.Entry(player).Property(p => p.Name).IsModified = true;

Upvotes: 2

Related Questions