Has anyone found a good way to use data annotations to prevent specifc properties from being updated in a json patch doc.
Model:
public class Entity
{
[DoNotAllowPatchUpdate]
public string Id { get; set; }
public string Name { get; set; }
public string Status { get; set; }
public string Action { get; set; }
}
Logic:
var patchDoc = new JsonPatchDocument<Entity>();
patchDoc.Replace(o => o.Name, "Foo");
//Prevent this from being applied
patchDoc.Replace(o => o.Id, "213");
patchDoc.ApplyTo(Entity);
The logic code is just an example of what the patch doc could look like coming from the client just generating in C# for quick testing purposes
I wrote an extension method for JsonPatchDocument; here's an abbreviated version:
public static void Sanitize<T>(this Microsoft.AspNetCore.JsonPatch.JsonPatchDocument<T> document) where T : class
{
for (int i = document.Operations.Count - 1; i >= 0; i--)
{
string pathPropertyName = document.Operations[i].path.Split("/", StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
if (typeof(T).GetProperties().Where(p => p.IsDefined(typeof(DoNotPatchAttribute), true) && string.Equals(p.Name, pathPropertyName, StringComparison.CurrentCultureIgnoreCase)).Any())
{
// remove
document.Operations.RemoveAt(i);
//todo: log removal
}
}
}
Add a minimal attribute:
[AttributeUsage(AttributeTargets.Property)]
public class DoNotPatchAttribute : Attribute
Apply the attribute to your class properties:
public class SomeEntity
{
[DoNotPatch]
public int SomeNonModifiableProperty { get; set; }
public string SomeModifiableProperty { get; set; }
}
Then you can call it before applying the transformation:
patchData.Sanitize<SomeEntity>();
SomeEntity entity = new SomeEntity();
patchData.ApplyTo(entity);