Easy Patch
A simple library to provide support for patching for you web api projects in a simple manner where you have control over what is going on.
Using the library
Asp.net Core
//Install the package
Install-Package EasyPatch.AspnetCore
//Register it in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options=> {
options.UseEasyPatch();
});
}
Asp.net
//Install the package
Install-Package EasyPatch.AspNetWebApi
// Configure it in your WebApi.Config
public static void Register(HttpConfiguration config)
{
// Other configurations here
config.UseEasyPatch();
}
Using the library in your api controllers
The Entity
// Basic model, this will be the model you apply the patch to, could be your db entity when using entity framework
public class User
{
public string Name { get; set; }
public string Username { get; set; }
}
The patch object
The Patch Object should derive from EasyPatchModelBase wich has two generics. The Type of the patch object, and the object to patch the data into. In our case that would be User
public class UserPatch : EasyPatchModelBase<UserPatch, User>
{
// UserPatchValidator: a validator that uses Fluent Validation to validate the incoming object.
public UserPatch() : base(new UserPatchValidator())
{
// Set the properties you want to map the data into, you can map any property to any property aslong as the types allow for it
AddPatchStateMapping(x => x.Name, x => x.Name);
AddPatchStateMapping(x => x.Username, x => x.Username);
}
public String Name { get; set; }
public String Username { get; set; }
// Override this method, to get a list of validation errors. This must be overriden in order to get validation messages
public override IEnumerable<KeyValuePair<string, string>> Validate()
{
return base.GetValidationErrors(this);
}
}
The Validator
public class UserPatchValidator : AbstractPatchValidator<UserPatch>
{
public UserPatchValidator()
{
//These rules apply allways proprty bound or not
//RuleFor(x => x.Name).NotNull();
//RuleFor(x => x.Username).NotNull();
//This rules apply only when the property is bound
WhenBound(x => x.Name, rule => rule.NotEmpty());
WhenBound(x => x.Username, rule => rule.NotEmpty());
}
}
If you need some properties to always be available when patching for example a **ModifyVersion** to keep track of changes so you don't override any then use the following rule
RuleFor(x => x.Name).NotNull();
This kind of rule will always be checked
If you want properties to only be validated when they are bound then use this type of validation
WhenBound(x => x.Name, rule => rule.NotEmpty());
this rule will only run when a property is bound, meaning its on the payload that comes in
# Api Controllers Aspnet Core
[HttpPatch]
public IActionResult Post([FromBody]UserPatch value)
{
// the modelstate will be populated with erors from the validator
if (!ModelState.IsValid) return BadRequest(ModelState);
var user = _db.Users.FirstOrDefault();
// assigns only the values that come in for patching
value.Patch(user);
return Ok(user);
}
# Api Controllers Aspnet
[HttpPatch]
public IHttpActionResult Post(TestPatchObject model)
{
// the modelstate will be populated with erors from the validator
if (!ModelState.IsValid) return BadRequest(ModelState);
var user = _db.Users.FirstOrDefault();
// assigns only the values that come in for patching
model.Patch(user);
return Ok(user);
}