ASP.NET Core 3.1系列(8)——Controller中的方法返回值

32 篇文章 43 订阅

1、前言

在之前的博客中大家可能会发现一个问题:Controller中的方法返回值都是string类型。其实之前只是为了演示方便,所以才统一使用string来表示返回结果。总的来说,Controller中的方法返回值一般分成三类:一般数据类型IActionResultActionResult<T>,下面开始逐一介绍。

2、一般数据类型

一般数据类型很简单,就是平时用到的intdoublestringIEnumerable等数据类型,代码如下所示:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        /// <summary>
        /// 获取年龄
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public int GetAge()
        {
            return 20;
        }

        /// <summary>
        /// 获取姓名
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string GetName()
        {
            return "张三";
        }

        /// <summary>
        /// 获取集合
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IEnumerable<Person> GetPersonList()
        {
            return new List<Person>
            {
                new Person { Name = "张三", Gender = "男", Age = 25, CreateTime = DateTime.Now },
                new Person { Name = "李四", Gender = "女", Age = 27, CreateTime = DateTime.Now  },
                new Person { Name = "王五", Gender = "男", Age = 26, CreateTime = DateTime.Now  }
            };
        }
    }
}

上面的代码看起来很不错,简洁明了、让人一眼就能看懂该方法的含义。但在实际使用过程中,它的缺陷就明显了:很难实现特殊情况下的逻辑处理。举个例子,现有如下情景:某方法接收一个int类型的参数id

  • id>0:返回集合
  • id=0:提示集合为空
  • id<0:提示参数错误

如果要完成上述逻辑,那我们的代码就得这么写,如下图所示:
在这里插入图片描述
很遗憾,上图中的代码连编译都通不过。因为方法的返回值是IEnumerable<Person>,但实际上在代码中却返回了string类型的变量。由此可见,一般数据类型作为方法返回值的局限性很大,

3、IActionResult类型

针对上面的问题,我们可以考虑使用IActionResult作为返回类型。该接口主要返回的是http的状态信息,如200401404等。在ASP.NET Core中,有多个类都实现了IActionResult接口,常用的一些类如下表所示:

状态码简写类名含义
200OkOkObjectResult成功返回
201CreatedCreatedResult资源被创建
204NoContentNoContentResult资源存在,但不返回结果
400BadRequestBadRequestObjectResult客户端一般性错误信息返回
401UnauthorizedUnauthorizedObjectResult未授权
404NotFoundNotFoundObjectResult找不到对应的信息

现在我们可以使用各种http状态码来处理特殊的逻辑了,代码如下:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get(int id = 1)
        {
            if (id > 0)
            {
                return Ok(new List<Person>
                {
                    new Person { Name = "张三", Gender = "男", Age = 25, CreateTime = DateTime.Now },
                    new Person { Name = "李四", Gender = "女", Age = 27, CreateTime = DateTime.Now },
                    new Person { Name = "王五", Gender = "男", Age = 26, CreateTime = DateTime.Now }
                });
            }
            else if (id == 0)
            {
                return NotFound("找不到数据");
            }
            else
            {
                return BadRequest("错误参数");
            }
        }
    }
}

上面的代码是简写形式,也可以写成如下形式,效果是一样的:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get(int id = 1)
        {
            if (id > 0)
            {
                return new OkObjectResult(new List<Person>
                {
                    new Person { Name = "张三", Gender = "男", Age = 25, CreateTime = DateTime.Now },
                    new Person { Name = "李四", Gender = "女", Age = 27, CreateTime = DateTime.Now },
                    new Person { Name = "王五", Gender = "男", Age = 26, CreateTime = DateTime.Now }
                });
            }
            else if (id == 0)
            {
                return new NotFoundObjectResult("找不到数据");
            }
            else
            {
                return new BadRequestObjectResult("错误参数");
            }
        }
    }
}

id>0时,运行结果如下图所示:
在这里插入图片描述
id=0时,运行结果如下图所示:
在这里插入图片描述
id<0时,运行结果如下图所示:
在这里插入图片描述

4、ActionResult< T >类型

微软在ASP.NET Core 2.1中引入了ActionResult<T>类型。其实ActionResult<T>IActionResult在功能上几乎没什么区别,但ActionResult<T>类型允许将一般数据类型和http状态信息混合使用,代码如下:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        public ActionResult<IEnumerable<Person>> Get(int id = 1)
        {
            if (id > 0)
            {
                return new List<Person>
                {
                    new Person { Name = "张三", Gender = "男", Age = 25, CreateTime = DateTime.Now },
                    new Person { Name = "李四", Gender = "女", Age = 27, CreateTime = DateTime.Now },
                    new Person { Name = "王五", Gender = "男", Age = 26, CreateTime = DateTime.Now }
                };
            }
            else if (id == 0)
            {
                return NotFound("找不到数据");
            }
            else
            {
                return BadRequest("错误参数");
            }
        }
    }
}

为什么ActionResult<T>能实现一般数据类型和http状态信息的混用呢?按F12导航到该类,如下图所示:
在这里插入图片描述
implicit operator表明这是一个隐式转换,即:ActionResult可以直接转换为ActionResult<TValue>类型。相较于IActionResult类型只能返回http状态信息,个人更推荐使用ActionResult类型。

5、结语

本文主要介绍了Controller中方法返回值问题。由于实际开发过程中的业务逻辑肯定会更加复杂,因此个人更推荐使用ActionResult<T>作为方法返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值