Prevent certain fields from being overwritten with PATCH in .NET Azure Web Api

I am creating an Azure Mobile Service with a .NET backend that uses TableController (a 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 AccountController, where I do not want to field Username

and UserId

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'd like to send a response HTTP request like 403: Forbidden

or similar if the client connecting to the API tries to update the username or userId. So I need some way to either find out the contents of the Delta patch, or get an autoresponder when "forbidden" fields are updated.

+3


source to share


1 answer


Not sure if there is a built-in way to do this. However, you can work around this. Create a new attribute, say NonEditable

.

public class NonEditableAttribute: Attribute 
{
}

      

Apply this attribute to properties that you do not want to fix.

public class Account
{
   [NonEditable]
   public string UserName {get;set;}

   ... other properties
}

      

Write some helper method that checks if changed properties Delta<T>

do not contain 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 it contains Delta<T>

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: The code is untested and could be better designed. This should give you a general idea - treat it as pseudocode.

+3


source







All Articles