ASP.net Core API 返回 ActionResult<T> 不强制返回类型

Spe*_*cer 9 c# asp.net-core-mvc .net-core asp.net-core-webapi

当 API 返回数据类型时,ActionResult<T>不会进行编译或运行时检查来确保返回的数据类型与声明的数据类型一致。

例如:

public ActionResult<Dog> GetCat()
{
    var cat = new Cat("Moggy");
    return Ok(cat);
}
Run Code Online (Sandbox Code Playgroud)

这会编译、运行并返回一个 Cat 对象。

我遇到的问题是 OpenAPI 定义 (Swagger/Swashbuckle) 是从方法上声明的类型派生的。这意味着 OpenAPI 定义可能与代码不同步,并且没有明显的方法来查找这些实例。

在给出的示例中,我的 API 文档会告诉人们该 API 返回的是 Dog,而实际上它返回的是 Cat。

有没有办法在编译时强制返回类型,或者在运行时失败?

Ren*_*ena 7

那是因为您返回的类型OkObjectResult继承了ActionResult. 返回的子类不会影响父类编译。这是设计使然。

关于这两个类的更多细节可以参考下面的源码:

1.该Ok方法返回类型OkObjectResult

// Summary:
//     A base class for an MVC controller without view support.
[Controller]
public abstract class ControllerBase
{       
      // Summary:
    //     Creates an Microsoft.AspNetCore.Mvc.OkObjectResult object that produces an Microsoft.AspNetCore.Http.StatusCodes.Status200OK
    //     response.
    //
    // Parameters:
    //   value:
    //     The content value to format in the entity body.
    //
    // Returns:
    //     The created Microsoft.AspNetCore.Mvc.OkObjectResult for the response.
    [NonAction]
    public virtual OkObjectResult Ok([ActionResultObjectValueAttribute] object value);
Run Code Online (Sandbox Code Playgroud)

2.OkObjectResult 继承ObjectResult

    //
// Summary:
//     An Microsoft.AspNetCore.Mvc.ObjectResult that when executed performs content
//     negotiation, formats the entity body, and will produce a Microsoft.AspNetCore.Http.StatusCodes.Status200OK
//     response if negotiation and formatting succeed.
[DefaultStatusCode(200)]
public class OkObjectResult : ObjectResult
{
    //
    // Summary:
    //     Initializes a new instance of the Microsoft.AspNetCore.Mvc.OkObjectResult class.
    //
    // Parameters:
    //   value:
    //     The content to format into the entity body.
    public OkObjectResult(object value);
}
Run Code Online (Sandbox Code Playgroud)

3.ObjectResult继承ActionResult

public class ObjectResult : ActionResult, IStatusCodeActionResult, IActionResult    
{
   public ObjectResult(object value);
   //..
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在编译时强制返回类型,或者在运行时失败?

ActionResult<T>使您能够返回派生自特定类型的类型ActionResult或返回特定类型。

要强制执行编译错误,您可以只返回特定类型的 cat。当您更改Dog为:时,您可以看到错误消息消失Cat

public ActionResult<Dog> GetCat()
{
    var cat = new Cat("Moggy");
    return cat;
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

在此输入图像描述