防止在.NET Azure Web Api中使用PATCH覆盖某些字段

时间:2014-11-21 11:55:46

标签: c# .net azure asp.net-web-api

我正在创建一个带有.NET后端的Azure移动服务,后端使用TableController(ApiController的子类)来处理REST请求。

在我的PATCH方法中,我想限制允许更新的字段集。我有一个AccountController,我不希望覆盖字段UsernameUserId

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);          
   }
...
}

如果连接到API的客户端尝试更新用户名或userId,我想发回一个有意义的HTTP响应,如403: Forbidden或类似的。所以我需要一些方法来了解Delta补丁的内容,或者在更新'禁用'字段时自动响应。

1 个答案:

答案 0 :(得分:3)

不确定是否有内置方法可以做到这一点。但是,您可以解决此问题。创建新属性,我们说NonEditable

public class NonEditableAttribute: Attribute 
{
}

将此属性应用于您不想修补的属性。

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

   ... other properties
}

编写一些帮助方法,检查Delta<T>上的更改属性是否包含任何这些不可编辑的属性。

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;
}

现在,在您的ApiController中,只需检查Delta<T>是否包含不可编辑的已更改属性

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...
   }
...
}

请注意:代码未经过测试,可以更好地设计。这是为了给你一般的想法 - 把它当作伪代码。