Search code examples
c#json.net

.NET API Update Includes ID


I come from a Ruby on Rails API background, but am currently working on a .NET C# WebAPI. I am familiar with C# and .NET webforms.

I'm attempting to set up a PUT request that will update a record in the db. The scaffolded method overwrites all the fields, whereas I want to simply update just the fields passed through the PUT. I attempted with the below code:

// PUT: api/Users/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutUser(string id, User user)
        {

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            User userToUpdate = db.Users.Where(u => u.id == id).FirstOrDefault();
            if (userToUpdate == null)
            {
                return NotFound();
            }

            db.Entry(userToUpdate).CurrentValues.SetValues(user);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateException)
            {
                if (UserExists(id))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

However, the method fails on db.SaveChanges() as it cannot overwrite 'id', which is a key. The put request is of content-type: application/json and the json is below:

{
    "preferredEmailUpdates":"true"
}

This needs to work for all fields and accept null entries. So the below is valid as well, and should update the field phone with null.

{
    "preferredEmailUpdates":"true",
    "phone":null
}

How do I update these values, while not updating the key?


Solution

  • You can consider using the PATCH HTTP verb and a Delta<T> object.

        [AcceptVerbs("Patch"), ResponseType(typeof(void))]
        public IHttpActionResult PatchUser(string id, Delta<Team> changes)
        {
            User userToUpdate = db.Users.Where(u => u.id == id).FirstOrDefault();
            if (userToUpdate == null) 
               return NotFound();
    
            changes.Patch(userToUpdate);
    
            try
            {                
                db.SaveChanges()
            }
            catch (DbUpdateException)
            {
               ...
            }
    
            return StatusCode(HttpStatusCode.NoContent);
        }
    

    See also Easy ASP.NET Web API resource updates with Delta.