Handling PATCH updates in a Web API service

I was working on a project where my client wanted a Web API service so various external portals could add and update members in CRM. Doing this I came across a problem called PATCH.

In the REST world it is very common to update items by only sending the changed data and leaving out the other variables. Let's imagine a "contact" entity where I only want to update the first name and leave the last name unchanged.

My REST call would only contain the first name and I wouldn't even send the last name along with the request. I would try something like this:

public IHttpActionResult UpdateContact(Guid contactId, Contact contact)
{
    using (var context = new CrmServiceContext(CrmService))
    {
        var c = new Contact();
        c.Id = contactId;

        if (contact.FirstName != null)
        {
            c.FirstName = contact.FirstName;
        }

        if (contact.LastName != null)
        {
            c.LastName = contact.LastName;
        }

        CrmService.Update(c);
        return Ok();
    }
}   

The problem in this case would be that I cannot see if the variable wasn't sent along or if the user wanted to empty the value by sending a null value.

Here the Delta class from the Microsoft ASP.NET WebAPI OData comes in handy..

After you install the NuGet package you can change the contact object to Delta<Contact> and this way you have access to the GetChangedPropertyNames() property.

public IHttpActionResult UpdateContact(Guid contactId, Delta<Contact> contact)
{
    using (var context = new CrmServiceContext(CrmService))
    {
        var changedProperties = contact.GetChangedPropertyNames().ToList();

        var c = new Contact();
        c.Id = contactId;

        if (changedProperties.Contains("FirstName"))
        {
            object changedProperty;
            contact.TryGetPropertyValue("FirstName", out changedProperty);
            c.FirstName = Convert.ToString(changedProperty);
        }

        if (changedProperties.Contains("LastName"))
        {
            object changedProperty;
            contact.TryGetPropertyValue("LastName", out changedProperty);
            c.LastName = Convert.ToString(changedProperty);
        }

        CrmService.Update(c);
        return Ok();
    }
}

Now I can determine with the changedProperties.Contains("PropertyName") if a property has changed and if I should empty it or leave it unchanged.

Beware this only appears to work when you post a JSON request with the Content-Type header properly set to application/json. I tried various ways to get it working with posted form data but the changedProperties list stays empty.

Comments (7) -

  • CathyRoberson

    10/19/2016 7:11:09 AM |

    I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It's always nice when you can not only be informed, but also entertained! I'm sure you had fun writing this article.

  • essay writing agency

    1/4/2017 9:36:45 AM |

    My husband is a programmer and I guess he will help me in it.

  • I unfortunately do not understand the programming. But I think that the characteristics of this accomodation it will be very useful for my friend. I share with them a link to your post.

  • buy an essay online

    1/28/2017 3:42:21 PM |

    That was something I wasn't aware about. I hope to see her more materials on that. It will be helpful.

  • http://edit-ing.services/

    2/8/2017 7:12:18 PM |

    Thanks, that was useful. I hope that you'll enlarge this topic, so I could make it by myself.

Loading