2017-04-11 34 views
9

我有一个asp.net核心Web API结构如下:如何在.net Core web API中构建数据验证?

View Layer: API endpoints 
    | 
    V 
Controller Layer: Controller classes implementing endpoints 
    | 
    V 
Business Logic Layer: Services 
    | 
    V 
Data Access Layer: Proxy classes to our backend 

有一系列的都遵循这种结构的端点。大多数API纯粹是对后端的数据查询,但一些API也允许调用客户端提交数据。

我正在努力寻找一种干净的方式来巩固必须在提交的数据上发生的各种验证。

我最初的意图是Controller层非常简单,并将所有真正的“工作”(包括验证)交给服务层,而Controller层只负责发送适当的HTTP响应。然而,我的问题是,在服务完成所有实际工作之后,如何最好地与控制器进行沟通,以便返回应该返回的内容。

我可以使用数据注释来捕获一些基本的验证,并且在大多数情况下,对于数据验证而言实际上可能已经足够了。但是,这并不像覆盖更复杂的验证,或者失败的服务/数据访问层WRT读/写等其他问题

我已经反复考虑的一些想法:

  • 充分利用服务层意识到IActionResult接口并使其负责确定要返回给调用客户端的内容。然后这混合了Controller和Service层,但使Controller层非常精简。

  • 为各种服务调用创建各种“OperationResults”对象,它们将封装由Controller层解释的任何错误消息,异常,错误代码等,以确定将什么http响应发送回客户端。这是一个更清晰的分离,因为服务层根本不会与http代码混合,但会将控制器类转换为一大组交换机来确定要发回的内容。

  • 根据在控制器与服务级别捕获的内容进行验证。例如,控制器传递一个空对象进行保存应该明确地拒绝它并返回BadRequest(),但当服务层也有自己的原因希望检查时,在那里添加检查似乎是多余的。

我承认在一般有点新的.NET网络API和.NET的核心,所以如果有可用的一些明显的功能我不接受的优势,我很想知道。

任何意见,将不胜感激,谢谢。

+0

异常应尽快提出,根据您的模型,您发现有问题,因此如果它可能被控制器捕获,请勿将其留给业务模型。如果某些功能是必要的但是是多余的,那么它会响应继承。 – Xaqron

+3

简短的回答是把它放在你的控制器动作中。无论什么架构,控制器都是第一道防线。服务层不应该有任何形式的验证。实际上你的服务层甚至不应该知道IActionResult是什么。查看[FluentValidation](https://github.com/JeremySkinner/FluentValidation)。它是一个成熟,稳定且广受欢迎的验证库。如果你缩小你的问题的范围,我会很高兴举出一些例子,但目前的形式有点宽泛。 – trevorc

回答

5

主要思想是正确的 - 您需要在代码中分离正常流和错误流。其中一种主要方法是使用.NET Exceptions来指示正常流程是不可能的。

  • 对于输入验证使用ActionFilter。您可以为所有控制器设置全局过滤器或定义特定的每个操作。请参阅文档中的Filters部分。

  • 在控制器操作执行期间,应尽快引发异常并停止进一步的执行。是的,异常可以在任何级别上提出(服务/业务层,DA层等)。

如何处理引发的异常?

使用ASP.NET Core提供的错误处理方法(如ExceptionHandler或Exception Filters),您可以分析异常并相应地生成适当/不同的响应。例如 查看相关SO Error handling in ASP.NET Core 1.0 Web API (Sending ex.Message to the client)问题。文档中还有error-handling section

+0

如果我需要本地化的错误消息,我该怎么办?如何处理异常类型,我们是否需要为特定的验证规则创建特定的异常? –

相关问题