【发布时间】:2015-07-08 06:03:40
【问题描述】:
假设您的 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 的模型类与 EF 实体是分开的,因为数据库架构与 API 对象模型不完全匹配。
【问题讨论】:
-
并不觉得它真的是注释的工作,因为它们感觉更像是业务规则而不是数据类型/合同检查。您通常不会通过从您的代码中进行简单的方法调用来处理这样的检查在后端说 'checkUserBelongsToFarm()';并且可能通过 API 返回 HTTP 400(错误请求)或 200(无内容)。如果一个库可供您的类使用或作为实用方法驻留在类本身中,则所有验证都可以存在。简单、快速的清洁...
-
@CodeUniquely 好吧,基于属性的验证具有将遇到的所有错误返回给客户端几乎不费力的优势。想象一下,模型很复杂,由多个集合中的多个实体类型组成。 ModelState 使在 json 中定位任何验证错误变得轻而易举。我没有看到一种简单的方法来降低我的模型结构并在不同的对象上调用不同的验证函数,然后将结果与 ModelState 返回的其他验证错误合并。这基本上是问题的症结所在。
-
没错,所以像你一样返回数据定义错误,但来自应用程序的逻辑错误。从模型的角度来看,如果允许 1-10,则值为 7,如果它也有效,则在其他地方“粉红色”。把它想象成一个 XML 模式——你可以定义各种类型的值,将它们传递进去,你可以根据模式进行验证,而不会引发任何错误。这并不意味着应用程序将允许它们一起使用。应用程序决定哪些值组合是有效的而不是模式解析器,并分别以适当的警告拒绝数据。
-
@CodeUnique你可能有一点。让我再考虑一下。
标签: c# .net entity-framework asp.net-web-api ninject