Ok()方法和new ObjectResult()之间有什么区别吗?

40

场景:在.NET Core控制器上实现标准的REST API / GET方法。

文档指出,OkObjectResult是状态码为200的ObjectResult。这可通过从ControllerBase继承的Ok(myResult)方法获得。我认为这是一种便利方式。

然而,教程并没有使用这种方法,而是返回new ObjectResult(myResult),默认状态码为200。

这两种方法之间有什么区别吗?

4个回答

51

从技术上讲,这两种方法之间没有区别。

如果你想查看OkObjectResult的代码,那么你会发现OkObjectResult是一个设置了200状态码的ObjectResult,而默认情况下ObjectResult已经设置了200状态码。

对我来说唯一的区别在于代码可读性以及你或你的团队的个人喜好。这一切都取决于命名和你想要强调的意图。

 return Ok(myResult);                  // gives emphasis on status, my personal favorite

 return new OkObjectResult(myResult);  // for me a little bit verbose and the same
                                       // effect as Ok; but states we return an Object

 return new ObjectResult(myResult);    // gives emphasis of the content that is returned

2
实际上,这个回答非常误导人。根据这份文档:https://learn.microsoft.com/en-us/dotnet/api/system.web.http.apicontroller.ok?view=aspnetcore-2.1ApiController有两个重载方法。Ok返回OkResult,而Ok<T>(T)返回OkObjectResult。区别在于OkResult返回状态码200,而OkObjectResult则表示它还返回了一些值。 - Sergey Zykov
1
因此,这不仅仅是“代码可读性”的问题。应始终使用ApiController.Ok方法。 - Sergey Zykov

6
更新: 原问题中的两种方法和被接受答案中的第三种方法现在已经被直接返回对象所取代。
 return myResult

以下是来自当前教程页面的相关示例和解释:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);    
    if (todoItem == null)
    {
        return NotFound();
    }    
    return todoItem;
}

GetTodoItems和GetTodoItem方法的返回类型是ActionResult< T >类型。ASP.NET Core会自动将对象序列化为JSON,并将JSON写入响应消息的正文中。对于这种返回类型,响应代码是200,假设没有未处理的异常。未处理的异常会被转换为5xx错误。

这是如何工作的?todoItem不是ActionResult<TodoItem>类型,而是TodoItem类型。为什么编译器没有报错? - Joerg
1
如果您需要比Microsoft在上面提供的更多信息,我建议您就此特定部分提出自己的SO问题。我没有详细了解它,一个适当的答案可能也不适合在评论中。 - PMBjornerud

4

我只能看到依赖于某些默认值和显式提供该值之间的差异 - 后者通常更好,使用OkObjectResult(或显式设置StatusCode)可以使您的意图更加清晰,这非常重要。 ObjectResult没有默认的StatusCode,实际上默认值为null。但是,HttpResponse有默认状态码200,因此无论如何都能正常工作。


2
作为一位对自己的代码进行单元测试的人,请注意以下内容: return Ok(myResult)return myResult之间有区别
当你使用Ok(myResult)时: 返回的ActionResult对象的Result属性将被填充。因此,您可以基于它编写断言。例如:
[Fact]
public async Task GetArticle_ArticleIsNotNull_ReturnsOkObjectResult()
{
    // Arrange
    const int number = 1;
    _articleRepository.GetArticleAsync(number).Returns(new Article());

    // Act
    var result = await _articleController.GetArticle(number);

    // Assert
    result.Result.Should().BeOfType<OkObjectResult>();
}

但是,如果你只使用return myResult在单元测试期间,Result属性仍然为null


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接