为什么我应该返回ActionResult而不是object?

12
假设我有一个应用程序.NET Core 2.1 Web API + Angular 7,为什么我应该总是返回ActionResult?这样做与下面的代码有什么区别:
public ActionResult<MyDTO> GetData(){
    return new MyDTO();
}

并且:

public MyDTO GetData(){
    return new MyDTO();
}
在这两种情况下,我都会在用户界面上收到对象,并且两者都返回代码200。因此,使用ActionResult只是一个好习惯吗?

无论哪种情况,我都将在用户界面上收到对象,并且两个函数都返回200代码。那么,使用ActionResult只是一个好的实践,还是有其他原因?


如果您返回null,应该返回什么状态码?在ActionResult的情况下,您必须返回Ok(myObject)BadRequest(ModelState)NotFound(request)或类似的内容。 - Oliver
你应该认真查看文档 https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.1 - Nkosi
5个回答

17

当您使用这个时:

public MyDTO GetData(){
    return new MyDTO();
}

除了抛出异常,您不能返回任何不是MyDTO实例的内容。

当您使用IActionResult<T>时,您在表达您可能返回MyDTO实例,但并不一定需要。您可以返回BadRequest,InternalServerError或其他适合API/业务需求的内容。

例如:

public IActionResult<MyDTO> GetData() 
{
    if (!User.Identity.IsAuthenticated)
    {
        return Forbidden();
    }

    var data = _someService.GetSomeData();

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

    return Ok(data);
}

1
将GetData()装饰上[Authorize]属性,以摆脱IsAuthenticated。 - Daniel B

5

什么是ActionResult?

ActionResult是一个抽象类,代表一个操作方法的结果。这个类继承自System.Object,只添加了一个额外的抽象方法ExecuteResult,派生自ActionResult的类将自己实现这个方法。

为什么ActionResult是抽象类?因为不同的控制器操作可以返回不同类型的结果,并且MVC仍然可以正确处理它们。

你可能已经猜到了,这种实现方式是因为ActionResult有许多派生类,而且你确实是对的。但是这些不同类型的结果究竟是什么? 它们分为三个部分:内容返回重定向状态结果,我们会依次看一下每种结果类型。

IActionResult返回类型适用于一个操作中可能存在多个ActionResult返回类型的情况。

ActionResult类型表示各种HTTP状态码。任何非抽象类从ActionResult派生而来都可以作为有效的返回类型。

此类别中一些常见的返回类型包括 BadRequestResult(400)NotFoundResult(404)OkObjectResult(200)

或者,可以使用ControllerBase类中的常规方法从操作中返回ActionResult类型。

参考1 参考2


4

基本上,当你返回一个对象时,你的代码必须传递该对象。

在你的情况下,一切都很好,一个MyDTOhttp 200一起返回。

但是让我们考虑以下情况:

public MyDTO GetData(){

    if (someValidationFailed)
    {
        //bad request, not authorized, forbidden etc.
        return BadRequest();
    }

    return new MyDTO();
}

那样不符合逻辑。一般来说:返回 IActionResult 可以让你更加灵活。


0

这取决于您的应用程序需要完成什么任务。 ActionResultIActionResult接口 的默认实现,该接口有一个ExecuteResultAsync(ActionContext) 方法。因此,如果您想要异步执行给定上下文的结果,则应使用该实现,而不是重复造轮子。

如果您不需要那么复杂的功能,那么直接返回您的对象即可。


0

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