【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端点

相关推荐
周杰伦fans17 小时前
C# required 关键字详解
开发语言·网络·c#
游乐码19 小时前
c#ArrayList
开发语言·c#
唐青枫20 小时前
C#.NET Monitor 与 Mutex 深入解析:进程内同步、跨进程互斥与使用边界
c#·.net
周杰伦fans20 小时前
cad文件选项卡不见了怎么办?
c#
llm大模型算法工程师weng21 小时前
Python敏感词检测方案详解
开发语言·python·c#
游乐码21 小时前
c#stack
开发语言·c#
橘子编程1 天前
编程语言全指南:从C到Rust
java·c语言·开发语言·c++·python·rust·c#
zztfj1 天前
C# 异步方法 async / await CancellationToken 设置任务超时并手动取消耗时处理
c#·异步
无风听海1 天前
.NET10之C# 中的is null深入理解
服务器·c#·.net
龙侠九重天1 天前
C# 机器学习数据处理
开发语言·人工智能·机器学习·ai·c#