I used Microsoft.AspNet.WebApi.OData for my project and I had some problems working with JSON (working with numbers in my case). Also, the OData package has some dependencies which, from my point of view, are too big for a single feature (~7MB with all dependecies).
So I developed a simple library which do what you are asking for: SimplePatch.
How to use
Install the package using:
Install-Package SimplePatch
Then in your controller:
[HttpPatch]
public IHttpActionResult PatchOne(Delta<Todo> todo)
{
if (todo.TryGetPropertyValue(nameof(Todo.id), out int id)) {
// Entity to update (from your datasource)
var todoToPatch = Todos.FirstOrDefault(x => x.id == id);
if (todoToPatch == null) return BadRequest("Todo not found");
todo.Patch(todoToPatch);
// Now todoToPatch is updated with new values
} else {
return BadRequest();
}
return Ok();
}
The library support massive patch too:
[HttpPatch]
public IHttpActionResult PatchMultiple(DeltaCollection<Todo> todos)
{
foreach (var todo in todos)
{
if (todo.TryGetPropertyValue(nameof(Todo.id), out int id))
{
// Entity to update (from your datasource)
var entityToPatch = Todos.FirstOrDefault(x => x.id == Convert.ToInt32(id));
if (entityToPatch == null) return BadRequest("Todo not found (Id = " + id + ")");
person.Patch(entityToPatch);
}
else
{
return BadRequest("Id property not found for a todo");
}
}
return Ok();
}
If you use Entity Framework, you have to add only two lines of code after the call to the Patch method:
entity.Patch(entityToPatch);
dbContext.Entry(entityToPatch).State = EntityState.Modified;
dbContext.SaveChanges();
Furthermore, you can exclude some properties to be updated when the Patch method is called.
Global.asax or Startup.cs
DeltaConfig.Init((cfg) =>
{
cfg.ExcludeProperties<Todo>(x => x.id);
});
This is usefull when you are working with an entity and you don't want to create a model.