Last active
January 20, 2022 13:08
-
-
Save tugberkugurlu/7318417 to your computer and use it in GitHub Desktop.
ASP.NET Web API Patch Sample.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} | |
} |
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
Does this work for nested objects? Say Car had a reference to an Engine type?