繁体   English   中英

C# 接口概念说明与 ASP.NET Core 中的 IActionResult

[英]C# interface concept clarification with IActionResult in ASP.NET Core

我试图了解 C#,了解了基础知识并开始在 ASP.NET 核心中进行尝试,但无法理解接口部分。

我知道接口就像 class 应该包含的合同,并且接口方法没有主体,例如:

interface IAnimal 
{
    void animalSound(); 
}

然后我们在 class 中提供实现,如下所示:

class Pig : IAnimal 
{
    public void animalSound() 
    {
        Console.WriteLine("The pig says: wee wee");
    }
}

但是,当我(像往常一样)进入现实世界时,情况有所不同:)

在 ASP.NET 内核中,我们可以使用IActionResult接口来帮助我们做出响应——返回Ok()NotFound()等。

就像在这个例子中

namespace CityInfo1.API.Controllers
{
    [ApiController]
    [Route("api/cities")]
    public class CitiesControllers : ControllerBase
    {
        [HttpGet]
        public IActionResult GetCities()
        {
            return Ok(CitiesDataStore.Current.Cities);
        }

        [HttpGet("{id}")]
        public IActionResult GetCity(int id)
        {
            var cityToReturn = CitiesDataStore.Current.Cities
                .FirstOrDefault(c => c.Id == id);

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

            return Ok(cityToReturn);
        }
    }
}

但在这里, IActionResult实际上是提供不同方法的功能和实现。

另一个问题,在IAnimal示例中,是否必须在使用此接口的类中使用AnimalSound() 如果是这样,是否可以将其设为可选?

IActionResult声明如下:

public interface IActionResult
{
    Task ExecuteResultAsync(ActionContext context);
}

与您的IAnimal非常相似,不是吗?

还有一个名为OkObjectResult的 class 实现IActionResult ,它有这个ExecuteResultAsync方法。

public class OkObjectResult : IActionResult {
    public Task ExecuteResultAsync(ActionContext context)
    {
        // ...
    }
}

OkObjectResult实际上并不直接实现IActionResult 它继承自ObjectResult ,后者继承自实现IActionResultActionResult 该代码仅用于说明目的。

这对应于您的非真实示例中的Pig class。

现在,您的CitiesController代码对应于非真实世界示例的哪一部分? 好吧,您在非现实世界的示例中错过了那部分。 如果我们继续它,我们可以说有一个AnimalFactory class 产生IAnimal s:

public class AnimalFactory {
    public IAnimal GetAnimal() {
        return new Pig();
    }
}

为了争论,假设AnimalFactory的用户不关心他们得到什么样的动物,只要它是IAnimal - 即具有animalSounds方法的东西。 作为实施者,我们可以自由决定返回哪种动物,在这种情况下,我决定总是返回一头猪。

回到您的CitiesController ,您应该在GetCity中返回一个IActionResult ,但调用者并不关心哪种特定类型的IActionResult ,只要它是一个IActionResult - 具有ExecuteResultAsync(ActionContext)方法。 您已决定返回Ok返回的任何内容(这是BaseController CitiesController的一种方法)。 仅供参考, OK返回OkObjectResult的一个实例。 现在你知道我为什么一开始就提到了!

是否必须在实现接口的类中声明AnimalSound()方法?

是的,因为通过实现接口,您是说 class 具有接口所需的所有成员。 声明您的 class 实现了一个接口,然后不提供所需的成员,这只是在撒谎,不是吗? :D

IActionResult 类型

当一个操作中可能有多个ActionResult返回类型时,IActionResult 返回类型是合适的。 ActionResult 类型代表各种 HTTP 状态代码。 任何派生自 ActionResult 的非抽象 class 都有资格作为有效的返回类型。 此类别中的一些常见返回类型是BadRequestResult (400)、 NotFoundResult (404) 和OkObjectResult (200)。 或者,可以使用ControllerBase class 中的便捷方法从操作返回 ActionResult 类型。 例如,返回 BadRequest(); 是 return new BadRequestResult(); 的简写形式。

因为在这种类型的操作中有多种返回类型和路径,所以需要自由使用 [ProducesResponseType] 属性。 此属性为 web API 帮助页面生成更多描述性响应详细信息,这些帮助页面由 Swagger 等工具生成。 [ProducesResponseType]表示动作要返回的已知类型和HTTP状态码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM