Skip to content

Instantly share code, notes, and snippets.

@tugberkugurlu
Last active January 20, 2022 13:08
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tugberkugurlu/7318417 to your computer and use it in GitHub Desktop.
Save tugberkugurlu/7318417 to your computer and use it in GitHub Desktop.
ASP.NET Web API Patch Sample.
public class Car {
public int Id { get; set; }
[Required]
[StringLength(20)]
public string Make { get; set; }
[Required]
[StringLength(20)]
public string Model { get; set; }
public int Year { get; set; }
[Range(0, 500000)]
public float Price { get; set; }
}
public class CarPatch
{
[StringLength(20)]
public string Make { get; set; }
[StringLength(20)]
public string Model { get; set; }
public int? Year { get; set; }
[Range(0, 500000)]
public float? Price { get; set; }
}
public class CarsController : ApiController
{
private readonly CarsContext _carsCtx = new CarsContext();
// PATCH /api/cars/{id}
public Car PatchCar(int id, CarPatch car)
{
var carTuple = _carsCtx.GetSingle(id);
if (!carTuple.Item1)
{
var response = Request.CreateResponse(HttpStatusCode.NotFound);
throw new HttpResponseException(response);
}
Patch<CarPatch, Car>(car, carTuple.Item2);
// Not required but better to put here to simulate the external storage.
if (!_carsCtx.TryUpdate(carTuple.Item2))
{
var response = Request.CreateResponse(HttpStatusCode.NotFound);
throw new HttpResponseException(response);
}
return carTuple.Item2;
}
// private helpers
private static ConcurrentDictionary<Type, PropertyInfo[]> TypePropertiesCache =
new ConcurrentDictionary<Type, PropertyInfo[]>();
private void Patch<TPatch, TEntity>(TPatch patch, TEntity entity)
where TPatch : class
where TEntity : class
{
PropertyInfo[] properties = TypePropertiesCache.GetOrAdd(
patch.GetType(),
(type) => type.GetProperties(BindingFlags.Instance | BindingFlags.Public));
foreach (PropertyInfo prop in properties)
{
PropertyInfo orjProp = entity.GetType().GetProperty(prop.Name);
object value = prop.GetValue(patch);
if (value != null)
{
orjProp.SetValue(entity, value);
}
}
}
}
@peheje
Copy link

peheje commented Mar 1, 2018

Does this work for nested objects? Say Car had a reference to an Engine type?

@bkojabash
Copy link

Seems like this implementation does not follow the Patch standards from https://tools.ietf.org/html/rfc7396

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment