I am creating an Azure Mobile Service with a .NET backend which uses a TableController (subclass of ApiController) to handle REST requests.
In my PATCH method I want to restrict the set of fields that are allowed to be updated. I have an AccountController where I don't want the fields Username
and UserId
to be overwritten.
public class AccountController : TableController<Account>
{
...
// PATCH tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Account> PatchAccount(string id, Delta<Account> patch)
{
return UpdateAsync(id, patch);
}
...
}
I would like to send back a meaningful HTTP response like 403: Forbidden
or similar if a client connecting to the API tries to update the username or userId. So I need some way of either knowing the content of the Delta patch or having an auto response when the 'forbidden' fields are being updated.
Not sure if there is a built-in way to do that. However, you can workaround this. Create new attribute, let's say NonEditable
.
public class NonEditableAttribute: Attribute
{
}
Apply this attribute to properties you don't want to be patched.
public class Account
{
[NonEditable]
public string UserName {get;set;}
... other properties
}
Write some helper method that will check if changed properties on Delta<T>
contains any of these non editable properties.
public bool IsValidDelta<T>(Delta<T> delta) where T: class
{
// list of property names that can't be patched
var nonEditablePropertyNames = from p in typeof(T).GetProperties()
let attr = p.GetCustomAttribute(typeof(NonEditableAttribute))
where attr != null
select p.Name;
// list of property names that were changed
var changedPropertyNames = delta.GetChangedPropertyNames();
// check if changedPropertyNames contains any of propertyNames,
// if yes return false, if no return true;
}
Now, in your ApiController, just check if Delta<T>
contains changed properties, that are not editable
public class AccountController : TableController<Account>
{
...
// PATCH tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Account> PatchAccount(string id, Delta<Account> patch)
{
if(IsValidDelta(patch))
return UpdateAsync(id, patch);
else
// forbidden...
}
...
}
Please Note: Code is not tested, and can be better designed. This is to give you general idea - treat it as pseudo code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With