C# 何时返回IHttpActionResult vs对象

C# 何时返回IHttpActionResult vs对象,c#,asp.net-web-api,C#,Asp.net Web Api,在使用ASP.NET Web API的示例中,我看到两种不同的方法用于将数据返回到调用jQuery函数。第一个方法返回类型为Client的对象,但我不确定第二个方法返回的是什么 方法#1(返回客户端对象) 如果第二个方法找到单个对象,是否有任何原因它不能返回客户机对象类型?第二个方法允许您只返回状态代码(如示例中的404),流式处理文件内容和其他类型的非对象内容。返回IHttpActionResult提供了一种良好的关注点分离 控制器可以专注于以最合理的方式响应请求(状态代码、错误消息等)。另一

在使用ASP.NET Web API的示例中,我看到两种不同的方法用于将数据返回到调用jQuery函数。第一个方法返回类型为
Client
的对象,但我不确定第二个方法返回的是什么

方法#1(返回
客户端
对象)


如果第二个方法找到单个对象,是否有任何原因它不能返回
客户机
对象类型?

第二个方法允许您只返回状态代码(如示例中的404),流式处理文件内容和其他类型的非对象内容。

返回
IHttpActionResult
提供了一种良好的关注点分离

控制器可以专注于以最合理的方式响应请求(状态代码、错误消息等)。另一个(服务)层可以专注于实际检索和转换业务数据

副作用是,控制器方法变得更易于单元测试。考虑下面的简单例子:

public class MyController : ApiController
{
    //or better yet, dependency-inject this
    SomeService _service = new SomeService();

    public IHttpActionResult Get(int id)
    {
         if (id < 0)
             return BadRequest("Some error message");

         var data = _service.GetData(id);

         if (data == null)
            return NotFound();

         return Ok(data);
    }
}
公共类MyController:ApiController
{
//或者更好的是,依赖注入这个
SomeService _service=新的SomeService();
公共IHttpActionResult Get(int id)
{
if(id<0)
返回错误请求(“某些错误消息”);
var data=_service.GetData(id);
如果(数据==null)
返回NotFound();
返回Ok(数据);
}
}
该方法的逻辑不仅可以通过阅读理解,而且现在您可以更轻松自然地测试逻辑,例如(使用NUnit语法):

[TestFixture]
公共类MyControllerTests
{    
[测试]
public void Get_withidless大于0_returnsAddressRequest()
{
var controller=new MyController();
int id=-1;
IHttpActionResult actionResult=controller.Get(id);
Assert.IsInstanceOf(actionResult);
}
}
类似地,您可以模拟服务层并测试当您向控制器提供已知的
id
参数时会发生什么,等等


这是一篇关于

的好文章,谢谢你的回答。仍然可以使用“IHttpActionResult”返回对象吗?或者,当您要返回单个对象或对象集合时,是否应该使用第一个方法?我问这个问题的原因是我正在经历的示例(Microsoft文章-)使用返回
IHttpActionResult
的方法来返回一个对象。我试图调整代码以返回实体框架对象。直接从方法返回对象有一些优点。方法签名将更好地定义它,并且该方法将更易于测试。通过抛出类型为
HttpResponseException
的异常,而不是通过
IHttpActionResult
返回状态代码,例如找不到对象时的404或错误输入数据的400。但是异常代价高昂,并且方法签名与API没有任何关系(而是API浏览器在没有其他信息的情况下从他们那里收集信息)WEB API的缺点是路由概念、HTTP层和OOP的结合并不总是有意义的。然而,在使用IHTHTPATAcOpREST的同时,也有一种方法。它是<代码> RealStyPyAtgult。异常只比一些东西贵。当考虑所有反射和I/O所需T时,将给定的请求发送到控制器代码中,然后将结果翻译成响应,抛出和捕获异常的额外开销是相当合理的。我仍然不认为大多数状态代码是“异常”。从语义的角度来看。例如,
404
应该是预期的。我同意一个对象提供了一个更具体的api。但我个人认为泛型将有助于最好地描述api
IHttpActionResult
。这更像是创建服务层的理由,而不是返回
IHttpActionResult
。一旦我们已经正确地分离了关注点,测试操作抛出特定的异常类型与测试它返回给定的操作结果类型一样简单。这正是我使用该测试用例作为示例的原因-在答案中编写代码很简单,但说明了这一点。如果您认为我的答案不正确,请添加您自己的答案效率高。
public IHttpActionResult GetClient(int clientId)
{
     using (var context = new PQRSModel.PQRSEntities())
     {
       context.Configuration.ProxyCreationEnabled = false;
       var client = context.Clients.FirstOrDefault(c = c.ID == clientId);
       if (client == null)
       {
         return NotFound();
       }
       return Ok(client);
     }
}
public class MyController : ApiController
{
    //or better yet, dependency-inject this
    SomeService _service = new SomeService();

    public IHttpActionResult Get(int id)
    {
         if (id < 0)
             return BadRequest("Some error message");

         var data = _service.GetData(id);

         if (data == null)
            return NotFound();

         return Ok(data);
    }
}
[TestFixture]
public class MyControllerTests
{    
    [Test]
    public void Get_WithIdLessThan0_ReturnsBadRequest()
    {
        var controller = new MyController();
        int id = -1;

        IHttpActionResult actionResult = controller.Get(id);

        Assert.IsInstanceOf<BadRequestErrorMessageResult>(actionResult);
    }
}