针对数据库的Webapi验证
本文关键字:Webapi 验证 数据库 | 更新日期: 2023-09-27 17:59:11
假设您的webapi调用创建的数据库对象如下:
class Task
{
public Guid AssignedUser {get; set;}
public Guid FarmId {get; set;}
public Guid FieldId {get; set;}
... etc
}
当在移动设备上创建新任务,并调用API在服务器上创建此任务时,我需要执行一些验证。使用DataAnnotations
属性可以很容易地执行一些验证,例如是否需要一个文件,或者是否在Range
内。
但假设我还需要验证以下内容:
- 当前用户(来自上下文)属于指定的服务器场
- AssignedUser属于指定的服务器场
- 字段属于指定的场,AssignedUser被分配给处理此字段的组
所有这些检查都需要数据库中的信息。我正在尝试使用ExpressiveAnnotations,有了它们我可以做一些类似的事情
[AssertThat("CurrentUserBelongsToThatFarm(FarmId)")]
public Guid FarmId {get; set;}
唯一的问题是,在代码进入我的控制器操作之前,在json脱盐过程中运行验证,我不知道如何注入数据库上下文,以便它可以用于验证函数。也就是说,我当然可以直接从IoC容器中查询它,但我宁愿不这样做。
有没有一种干净的方法来进行这种验证?
更新
为了解决CodeUniquely在下面的评论,我想澄清一下,这是一个"偶尔连接"的场景。也就是说,使用API的设备大部分时间都在网络覆盖范围之外,并且它们不时使用API进行同步。
实际上,这意味着需要同步的大多数数据都被聚合为零个或一个"向服务器推送更新"调用,然后是"从服务器获取最新状态"调用。Sql Server和EF位于后端,导致多个不同(有时不相关)的实体和集合包含在单个json中。例如:
class TaskData
{
public IList<Product> Products {get; set;}
public Task Task {get; set}
...
}
此外,用于为GET调用生成json的模型类与EFEntites是分开的,因为数据库模式与API对象模型并不完全匹配。
我最终在这里做了以下事情。
我将所有验证划分为两个集合"立即",它们基于属性,不需要数据库和"数据库"。如果任何"立即"验证失败,请求将失败并将这些错误返回给客户端。理论上,只有当客户端没有正确验证这些客户端时,这些操作才会失败。否则,这些总会成功。
如果"立即"验证成功,我将对每个对象运行"数据库"验证。我将通过验证的更改持久化到DB,并为未通过验证的对象返回错误。
这或多或少是@CodeUniquely在他的评论中建议的。