C# 针对数据库的Webapi验证

C# 针对数据库的Webapi验证,c#,.net,entity-framework,asp.net-web-api,ninject,C#,.net,Entity Framework,Asp.net Web Api,Ninject,假设您的webapi调用创建如下数据库对象: class Task { public Guid AssignedUser {get; set;} public Guid FarmId {get; set;} public Guid FieldId {get; set;} ... etc } 当在移动设备上创建新任务并调用API在服务器上创建此任务时,我需要执行一些验证。使用DataAnnotations属性可以很容易地执行验证,例如是否需要一个字段,或者是否在范围内,或者什么都

假设您的webapi调用创建如下数据库对象:

class Task
{
  public Guid AssignedUser {get; set;}
  public Guid FarmId {get; set;}
  public Guid FieldId {get; set;}
  ... etc
}
当在移动设备上创建新任务并调用API在服务器上创建此任务时,我需要执行一些验证。使用
DataAnnotations
属性可以很容易地执行验证,例如是否需要一个字段,或者是否在
范围内,或者什么都不需要

但假设我还需要验证以下内容:

  • 当前用户(来自上下文)属于指定的服务器场
  • AssignedUser属于指定的服务器场
  • 字段属于指定的场,AssignedUser分配给处理此字段的组
所有这些检查都需要来自数据库的信息。我试着使用它们,用它们我可以做一些类似的事情

[AssertThat("CurrentUserBelongsToThatFarm(FarmId)")]
public Guid FarmId {get; set;}
唯一的问题是,验证在json脱盐过程中运行,在代码进入控制器操作之前,我无法确定如何注入数据库上下文,以便它可以用于验证函数。也就是说,我当然可以直接从IoC容器中查询它,但我不希望这样

是否有一种干净的方法来执行此类验证

更新

为了回应CodeUnique下面的评论,我想澄清一下,这是一个“偶尔连接”的场景。也就是说,使用API的设备大部分时间都不在网络覆盖范围内,并且它们会不时使用API进行同步

实际上,这意味着同步所需的大多数数据被聚合为零或一个“向服务器推送更新”调用,然后是“从服务器获取最新状态”调用。Sql Server和EF位于后端,导致多个不同(有时不相关)的实体和集合包含在单个json中。例如:

class TaskData
{ 
    public IList<Product> Products {get; set;} 
    public Task Task {get; set}
    ...
}
类任务数据
{ 
公共IList产品{get;set;}
公共任务任务{get;set}
...
}

另外,用于生成GET调用的json的模型类与EF Entite是分开的,因为数据库模式与API对象模型并不完全匹配。

我在这里做的是以下内容

我将所有验证拆分为两个“立即”集,它们基于属性,不需要数据库和“数据库”。如果任何“即时”验证失败,请求将失败并将这些错误返回给客户端。理论上,只有当客户端没有正确地验证这些客户端时,这些测试才会失败。否则,这些将永远成功

如果“立即”验证成功,我将对每个对象运行“数据库”验证。对于通过验证的更改,我将更改持久化到DB中,对于未通过验证的对象,我将返回错误


这或多或少是@CodeUnique在其评论中建议的。

感觉这并不是注释真正的工作,因为它们更像是业务规则,而不是数据类型/合同检查。通常情况下,您是否只需要在后端通过从代码中调用一个简单的方法来处理这样的检查,比如“checkUserBelongsToFarm()”;可能通过API返回HTTP 400(错误请求)或200(无内容)。如果您的类可以使用一个库,或者作为实用方法驻留在类本身中,那么所有的验证都可以有效。简单、快速的清理…@code唯一的优势是,基于属性的验证几乎不费吹灰之力就将遇到的所有错误返回给客户端。假设模型是复杂的,由多个集合中的多个实体类型组成。ModelState使在json中查找任何验证错误变得轻而易举。我看不到一种简单的方法来降低我的模型结构,对不同的对象调用不同的验证函数,然后将结果与ModelState返回的其他验证错误合并。这基本上是问题的症结所在。是的,确实如此,所以返回数据定义错误,就像您所做的一样,但是从应用程序返回逻辑错误。从模型的角度来看,如果允许1-10,则值为7,如果其也有效,则在其他地方为“粉红色”,这并没有错。把它想象成一个XML模式——您可以定义所有排序值,将它们传递进来,并且可以根据模式进行验证,而不会抛出任何错误。这并不意味着应用程序将允许它们一起使用。应用程序决定哪些值的组合是有效的,而不是架构解析器,并分别拒绝带有适当警告的数据。@CodeUnique您可能有道理。让我再想想。