我正在创建一个带有.NET后端的Azure移动服务,后端使用TableController(ApiController的子类)来处理REST请求。
在我的PATCH方法中,我想限制允许更新的字段集。我有一个AccountController,我不希望覆盖字段Username
和UserId
。
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补丁的内容,或者在更新'禁用'字段时自动响应。
答案 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...
}
...
}
请注意:代码未经过测试,可以更好地设计。这是为了给你一般的想法 - 把它当作伪代码。