合同要求在web api中进行验证

时间:2015-11-17 19:00:11

标签: c# asp.net-mvc asp.net-web-api code-contracts

我正在开发基于MVC5 / Web API的应用程序。在一些文章中,我已阅读使用Contract.RequiresSystem.Diagnostics.Contracts命名空间的一部分)来验证传入数据。

这是验证传入数据的正确方法吗?此外,我无法调试Contract.Requires行,因为调试器始终绕过此行。我正在使用Visual Studio 2013。

    public async Task<UserInfo> Put(
        [FromBody] UserInfo userInfo) {
        Contract.Requires(userInfo != null);
        ..............
     }

有人可以解释何时使用Contract.Requires以及在哪里避免?

3 个答案:

答案 0 :(得分:3)

您当然可以在控制器中使用代码合同,但这里有一些缺点和原因,您可能不需要合同。

  • API响应中错误详细信息丢失:代码合同失败将作为HTTP 500内部服务器错误返回给客户端,可能没有详细信息,这对客户端无效API。这是因为合同失败会导致抛出异常。您可能更愿意使用自己的详细信息抛出HttpResponseException,或者自定义HttpResponseMessage。在这种情况下(除非你滚动自己的全局异常处理)代码合同可能没有意义。

  • Contract.Requires可能是多余的:考虑Web API如何验证您的参数。例如,缺少参数可能导致无效路由,因此请求被拒绝,并且不会调用该方法。代码合同在这种方法中没用。

  • 为什么需要合同?代码合同非常适合在编译时捕获合同失败。但除非您的API客户端也是.NET项目,否则您无法利用该功能。因此,请考虑您可能需要签订合同的其他内容以及是否证明其合理使用。

答案 1 :(得分:3)

为什么要签约?

你可以在api方法中使用HttpResponseMessage:

[HttpPost]
    public HttpResponseMessage Put(UserInfo userInfo) {
     if(ModelState.IsValid)
    {
     // your code
    return Request.CreateResponse(HttpStatusCode.OK);
    }
    else
    {
    return Request.CreateResponse(HttpStatusCode.BadRequest, new { msg = "invalid data" });
    }
    }

和或:

  [HttpPost]
        public async Task<ActionResult> Put(UserInfo userInfo) {
         if(ModelState.IsValid)
        {
         // your code
        return Request.CreateResponse(HttpStatusCode.OK);
        }
        else
        {
        return Request.CreateResponse(HttpStatusCode.BadRequest, new { msg = "invalid data" });
        }
        }

答案 2 :(得分:2)

虽然Keith指出了在Web中使用代码契约的一些明显的缺点。我想分享一些关于它们可能有意义或派上用场的想法。

使用代码约定,您可以使用标准方法进行输入验证和参数验证(如断言甚至后置条件)。 这意味着您可以以相同的方式编码 - 无论您是在ApiController内还是在其他一些代码中(例如异步工作线程)。

当然,发送到客户端的一般HTTP 500消息没有用,因此我们将代码约定与标准Web.Api异常处理程序(HttpStatusExceptionFilterAttribute)结合使用。此异常处理程序将检查消息并将自定义HTTP错误代码发送回客户端(可选地连同失败的条件)以及它可以将完整堆栈跟踪记录到中央应用程序的日志工具。

通过利用这两个功能,您可以清理和简化代码,同时向客户端提供友好且有意义的错误信息,同时仍保留完整的错误信息以进行内部故障排除。

您可以查看本文,进一步解释它:Using CodeContracts with OData Controllers and Web.Api Exception Filters

希望这会有所帮助

问候,罗纳德