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

相关推荐
m5655bj3 小时前
使用 C# 将 Excel 表格转换为 DataTable
数据库·c#
LcVong3 小时前
基于C#实现斑马ZT411打印机TCP通讯与打印状态精准判定
网络·tcp/ip·c#
2501_930707783 小时前
使用C#代码在 Word 文档页面中添加装订线
开发语言·c#·word
曲幽3 小时前
C#异步与多线程:从入门到实战,避免踩坑的完整指南
c#·thread·async·await·csharp
初级代码游戏13 小时前
C#:程序发布的大小控制 裁剪 压缩
c#·.net·dotnet·压缩·大小·发布·裁剪
量子物理学16 小时前
Modbus TCP
c#·modbus tcp
人工智能AI技术17 小时前
能用C#开发AI吗?
人工智能·c#
自己的九又四分之三站台20 小时前
6. 简单将原生代码改为流式请求
c#
一叶星殇1 天前
C# .NET 如何解决跨域(CORS)
开发语言·前端·c#·.net