【WebApi】C#创建WebApi学习

1、创建WebApi项目

Prgram.cs代码保留如下

cs 复制代码
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();

app.Run();

2、Minmal APIs最小API使用

Prgram.cs中进行最小API使用

cs 复制代码
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();

//获取所有衬衫数据列表
app.MapGet("/shirts", () =>
{
    return "获取所有衬衫数据列表";
});

//获取指定ID的衬衫数据
app.MapGet("/shirts/{id}", (int id) =>
{
    return $"获取ID为 {id} 的衬衫数据";
});

//创建一件新的衬衫
app.MapPost("/shirts", () =>
{
    return "创建一件新的衬衫";
});

//更新指定ID的衬衫数据
app.MapPut("/shirts/{id}", (int id) =>
{
    return $"更新ID为 {id} 的衬衫数据";
});

//删除指定ID的衬衫数据
app.MapDelete("/shirts/{id}", (int id) =>
{
    return $"删除ID为 {id} 的衬衫数据";
});

app.Run();

3、ASP.NET Core中间件管道

app中的Use开头的方法都是中间件组件使用方法

4、Web API控制器实现Web API

方法1:将路由写在方法前面并指定操作动词

cs 复制代码
using Microsoft.AspNetCore.Mvc;

namespace WebApiTest.Controllers
{
    [ApiController]
    public class ShirtsController : ControllerBase
    {
        //获取所有衬衫数据列表
        [HttpGet]
        [Route("api/shirts")]
        public string GetShirts()
        {
            return "获取所有衬衫数据列表";
        }

        //获取指定ID的衬衫数据
        [HttpGet]
        [Route("api/shirts/{id}")]
        public string GetShirtById(int id)
        {
            return $"获取ID为 {id} 的衬衫数据";
        }

        //创建一件新的衬衫
        [HttpPost]
        [Route("api/shirts")]
        public string CreateShirt()
        {
            return "创建一件新的衬衫";
        }

        //更新指定ID的衬衫数据
        [HttpPut]
        [Route("api/shirts/{id}")]
        public string UpdateShirt(int id)
        {
            return $"更新ID为 {id} 的衬衫数据";
        }

        //删除指定ID的衬衫数据
        [HttpDelete]
        [Route("api/shirts/{id}")]
        public string DeleteShirt(int id)
        {
            return $"删除ID为 {id} 的衬衫数据";
        }
    }
}

方法2:将路由写在类前面,再在方法前面指定操作动词

cs 复制代码
using Microsoft.AspNetCore.Mvc;

namespace WebApiTest.Controllers
{
    [ApiController]
    [Route("/api/[controller]")]
    public class ShirtsController : ControllerBase
    {
        //获取所有衬衫数据列表
        [HttpGet]
        public string GetShirts()
        {
            return "获取所有衬衫数据列表";
        }

        //获取指定ID的衬衫数据
        [HttpGet("{id}")]
        public string GetShirtById(int id)
        {
            return $"获取ID为 {id} 的衬衫数据";
        }

        //创建一件新的衬衫
        [HttpPost]
        public string CreateShirt()
        {
            return "创建一件新的衬衫";
        }

        //更新指定ID的衬衫数据
        [HttpPut("{id}")]
        public string UpdateShirt(int id)
        {
            return $"更新ID为 {id} 的衬衫数据";
        }

        //删除指定ID的衬衫数据
        [HttpDelete("{id}")]
        public string DeleteShirt(int id)
        {
            return $"删除ID为 {id} 的衬衫数据";
        }
    }
}

5、基于控制器的Web API的路由

使用注解[Route("/shirts")]设置Web API的URL,可以在方法前使用,也可以在类前使用

方法前

类前

6、模型绑定,将Http请求中的数据映射到操作方法的参数

6.1 从路由绑定,在路由Route("/shirts/{id}")或在操作动词HttpGet("{id}")设置,在方法参数前设置[FromRoute]也可以省略

cs 复制代码
        [HttpGet("{id}")]
        public string GetShirtById([FromRoute]int id)
        {
            return $"获取ID为 {id} 的衬衫数据";
        }

6.2 从查询字符串中绑定,方法参数前使用注解[FromQuery]

http://localhost:5186/api/shirts/1?color=红色

cs 复制代码
        [HttpGet("{id}")]
        public string GetShirtById([FromRoute]int id, [FromQuery]string color)
        {
            return $"获取ID为 {id} 的衬衫数据";
        }

6.3 从请求头Header中绑定,方法参数前使用注解[FromHeader]

cs 复制代码
        [HttpGet("{id}")]
        public string GetShirtById([FromRoute]int id, [FromQuery]string color, [FromHeader]int size)
        {
            return $"获取ID为 {id} 的衬衫数据,衬衫颜色为{color},大小为{size}";
        }

6.4 从请求体Body JSON格式中绑定,方法参数前使用注解[FromBody]

cs 复制代码
        [HttpPost]
        public string CreateShirt([FromBody]Shirt shirt)
        {
            return $"创建一件新的衬衫,{shirt.Id}, {shirt.Name}, {shirt.Color}, {shirt.Gender}, {shirt.Price}";
        }

6.5 从请求体Body 表单中绑定,方法参数前使用注解[FromForm]

cs 复制代码
        [HttpPost]
        public string CreateShirt([FromForm]Shirt shirt)
        {
            return $"创建一件新的衬衫,{shirt.Id}, {shirt.Name}, {shirt.Color}, {shirt.Gender}, {shirt.Price}";
        }

7、数据注解模型验证

8、ValidationAtteibute模型验证,继承ValidationAttribute

创建脚本Shirt_EnsureCorrectSizingAttribute.cs

cs 复制代码
using System.ComponentModel.DataAnnotations;
using WebApiDemo.Models;

namespace WebApiTest.Models.Validations
{
    public class Shirt_EnsureCorrectSizingAttribute : ValidationAttribute
    {
        protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
        {
            var shirt = validationContext.ObjectInstance as Shirt;
            if(shirt != null && !string.IsNullOrEmpty(shirt.Gender))
            {
                if(shirt.Gender.Equals("men", StringComparison.OrdinalIgnoreCase) && shirt.Size < 8)
                {
                    return new ValidationResult("男性衬衫的尺码必须大于或等于8。");
                }
                else if (shirt.Gender.Equals("women", StringComparison.OrdinalIgnoreCase) && shirt.Size < 6)
                {
                    return new ValidationResult("女性衬衫的尺码必须大于或等于6。");
                }
            }

            return ValidationResult.Success;
        }
    }
}

在属性前添加注解

9、Web API返回类型

返回类型使用IActionResult

正确返回使用 Ok(返回数据)

未找到使用 NotFound()

错误响应使用 BadRequest()

cs 复制代码
        [HttpGet("{id}")]
        public IActionResult GetShirtById([FromRoute]int id, [FromQuery]string color, [FromHeader]int size)
        {
            if(id <= 0)
            {
                //错误响应
                return BadRequest();
            }
            else if(id > 10)
            {
                //未找到
                return NotFound();
            }

            //正确响应
            return Ok($"获取ID为 {id} 的衬衫数据,衬衫颜色为{color},大小为{size}");
        }

10、操作过滤器进行模型验证,继承ActionFilterAttribute

用户输入传递的id可能不符合规范,可以通过操作过滤器进行模型验证对id进行验证

创建脚本Shirt_ValidateShirtIdFilterAttribute

cs 复制代码
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace WebApiTest.Filters.ActionFilters
{
    public class Shirt_ValidateShirtIdFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);

            var id = context.ActionArguments["id"] as int?;
            if (id.HasValue)
            {
                if(id.Value <= 0)
                {
                    context.ModelState.AddModelError("Id", "衬衫ID必须大于0。");
                    var problemDetails = new Microsoft.AspNetCore.Mvc.ValidationProblemDetails(context.ModelState)
                    {
                        Status = 400,
                        Title = "请求参数错误",
                    };
                    context.Result = new BadRequestObjectResult(problemDetails);
                }
            }
        }
    }
}

需要使用验证的方法前添加注解

11、异常过滤器实现异常处理

更新衬衫之前可能其他请求把该衬衫已经删掉,更新时可能会报错,模拟该情景

创建脚本Shirt_HandleUpdateExceptionFilterAttribute

cs 复制代码
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace WebApiTest.Filters.ExceptionFilters
{
    public class Shirt_HandleUpdateExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public int?[] shirtsId = new int?[] { 1, 2, 3, 4, 5 };

        public override void OnException(ExceptionContext context)
        {
            base.OnException(context);

            //判断衬衫ID是否存在 暂时假设shirtsId为数据库中已有的衬衫ID列表
            var strShirtId = context.RouteData.Values["id"] as string;
            if (int.TryParse(strShirtId, out int shirtId))
            {
                if (shirtsId.FirstOrDefault(x => x == shirtId) == null)
                {
                    context.ModelState.AddModelError("Id", $"衬衫已经不存在");
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Status = StatusCodes.Status404NotFound,
                    };
                    context.Result = new NotFoundObjectResult(problemDetails);
                }
            }
        }
    }
}

在需要异常处理的方法前使用

12、Web API操作数据库

案例使用SqlServer数据库

12.1 安装需要使用的包

12.2 创建数据库上下文

12.3 执行数据库迁移

12.4 使用EF Core实现Get端点

12.5 使用EF Core实现Get by Id端点

12.6 使用EF Core实现Post端点

12.7 使用EF Core实现Put端点

12.8 使用EF Core实现Delete端点

相关推荐
mudtools1 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的2 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
唐宋元明清21882 天前
.NET 本地Db数据库-技术方案选型
windows·c#
lindexi2 天前
dotnet DirectX 通过可等待交换链降低输入渲染延迟
c#·directx·d2d·direct2d·vortice
qq_454245032 天前
基于组件与行为的树状节点系统
数据结构·c#
bugcome_com2 天前
C# 类的基础与进阶概念详解
c#
雪人不是菜鸡2 天前
简单工厂模式
开发语言·算法·c#
铸人2 天前
大数分解的Shor算法-C#
开发语言·算法·c#
未来之窗软件服务2 天前
AI人工智能(二十四)错误示范ASR张量错误C#—东方仙盟练气期
开发语言·人工智能·c#·仙盟创梦ide·东方仙盟
yong99902 天前
基于C#实现的UPnP端口映射程序
开发语言·c#