针对数据库的 Webapi 验证
Webapi validation against database
假设您的 webapi 调用创建了这样的数据库对象:
class Task
{
public Guid AssignedUser {get; set;}
public Guid FarmId {get; set;}
public Guid FieldId {get; set;}
... etc
}
当在移动设备上创建新任务并调用 API 在服务器上创建此任务时,我需要执行一些验证。使用 DataAnnotations
属性可以很容易地执行一些验证,例如是否需要一个文件或在 Range
之内或什么不是。
但假设我还需要验证以下内容:
- 当前用户(来自上下文)属于指定场
- AssignedUser 属于指定的农场
- Field 属于指定的 Farm,AssignedUser 分配给处理该 Field 的组
所有这些检查都需要来自数据库的信息。我正在尝试使用 ExpressiveAnnotations 并且与它们一起我可以做类似
的事情
[AssertThat("CurrentUserBelongsToThatFarm(FarmId)")]
public Guid FarmId {get; set;}
唯一的问题是,验证在 json 脱盐过程中运行,在代码进入我的控制器操作之前,我不知道如何注入数据库上下文,以便它可用于验证功能。那就是我当然可以直接从IoC容器中查询它,但我宁愿不这样做。
是否有执行此类验证的简洁方法?
更新
为了解决 CodeUniquely 在下方的评论,我想澄清一下,这是一个 "occasionally connected" 场景。也就是说,使用 API 的设备大部分时间都不在网络覆盖范围内,它们会不时使用 API 进行同步。
实际上,这意味着需要同步的大部分数据都聚合到零个或一个 "push updates to server" 调用中,然后是 "get latest state from server" 调用。在后端使用 Sql 服务器和 EF,导致多个不同(有时不相关)的实体和集合包含在单个 json 中。例如:
class TaskData
{
public IList<Product> Products {get; set;}
public Task Task {get; set}
...
}
此外,用于为 GET 调用生成 json 的模型 类 与 EF 实体是分开的,因为数据库架构与 API 对象模型不完全匹配。
我最终在这里做的是以下内容。
我将所有验证分为两组 "Immediate",它们是基于属性的,不需要数据库和 "Database"。如果任何 "Immediate" 验证失败,则请求失败并且 return 将这些错误发送给客户端。理论上,只有在客户端没有正确验证这些客户端时,这些才会失败。否则这些总会成功。
如果 "Immediate" 验证成功,我将对每个对象进行 运行 "Database" 验证。对于通过验证的更改和未通过验证的对象的 return 错误,我坚持对数据库的更改。
这或多或少是@CodeUniquely 在他的评论中建议的。
假设您的 webapi 调用创建了这样的数据库对象:
class Task
{
public Guid AssignedUser {get; set;}
public Guid FarmId {get; set;}
public Guid FieldId {get; set;}
... etc
}
当在移动设备上创建新任务并调用 API 在服务器上创建此任务时,我需要执行一些验证。使用 DataAnnotations
属性可以很容易地执行一些验证,例如是否需要一个文件或在 Range
之内或什么不是。
但假设我还需要验证以下内容:
- 当前用户(来自上下文)属于指定场
- AssignedUser 属于指定的农场
- Field 属于指定的 Farm,AssignedUser 分配给处理该 Field 的组
所有这些检查都需要来自数据库的信息。我正在尝试使用 ExpressiveAnnotations 并且与它们一起我可以做类似
的事情[AssertThat("CurrentUserBelongsToThatFarm(FarmId)")]
public Guid FarmId {get; set;}
唯一的问题是,验证在 json 脱盐过程中运行,在代码进入我的控制器操作之前,我不知道如何注入数据库上下文,以便它可用于验证功能。那就是我当然可以直接从IoC容器中查询它,但我宁愿不这样做。
是否有执行此类验证的简洁方法?
更新
为了解决 CodeUniquely 在下方的评论,我想澄清一下,这是一个 "occasionally connected" 场景。也就是说,使用 API 的设备大部分时间都不在网络覆盖范围内,它们会不时使用 API 进行同步。
实际上,这意味着需要同步的大部分数据都聚合到零个或一个 "push updates to server" 调用中,然后是 "get latest state from server" 调用。在后端使用 Sql 服务器和 EF,导致多个不同(有时不相关)的实体和集合包含在单个 json 中。例如:
class TaskData
{
public IList<Product> Products {get; set;}
public Task Task {get; set}
...
}
此外,用于为 GET 调用生成 json 的模型 类 与 EF 实体是分开的,因为数据库架构与 API 对象模型不完全匹配。
我最终在这里做的是以下内容。
我将所有验证分为两组 "Immediate",它们是基于属性的,不需要数据库和 "Database"。如果任何 "Immediate" 验证失败,则请求失败并且 return 将这些错误发送给客户端。理论上,只有在客户端没有正确验证这些客户端时,这些才会失败。否则这些总会成功。
如果 "Immediate" 验证成功,我将对每个对象进行 运行 "Database" 验证。对于通过验证的更改和未通过验证的对象的 return 错误,我坚持对数据库的更改。
这或多或少是@CodeUniquely 在他的评论中建议的。