.Net WebAPI(一)


文章目录

  • 项目地址
  • 一、WebAPI基础
    • [1. 项目初始化](#1. 项目初始化)
      • [1.1 创建简单的API](#1.1 创建简单的API)
        • [1.1.1 get请求](#1.1.1 get请求)
        • [1.1.2 post请求](#1.1.2 post请求)
        • [1.1.3 put请求](#1.1.3 put请求)
        • [1.1.4 Delete请求](#1.1.4 Delete请求)
      • [1.2 webapi的流程](#1.2 webapi的流程)
    • 2.Controllers
      • [2.1 创建一个shirts的Controller](#2.1 创建一个shirts的Controller)
    • [3. Routing](#3. Routing)
      • [3.1 使用和创建MapControllers](#3.1 使用和创建MapControllers)
      • [3.2 使用Routing的模板语言](#3.2 使用Routing的模板语言)
    • [4. Mould Binding](#4. Mould Binding)
      • [4.1 指定数据的来源](#4.1 指定数据的来源)
        • [4.1.1 给Request请求添加](#4.1.1 给Request请求添加)
          • [1. FromRoute](#1. FromRoute)
          • [2. FromQuery](#2. FromQuery)
          • [3. FromHeader](#3. FromHeader)
        • [4.1.2 给Post请求添加](#4.1.2 给Post请求添加)
          • [1. FromBody](#1. FromBody)
          • [2. FromForm](#2. FromForm)
    • [5. Mould Validation](#5. Mould Validation)
      • [5.1 添加Model Validation](#5.1 添加Model Validation)
      • [5.2 添加自定义的Validation](#5.2 添加自定义的Validation)
    • [6. WebApi Return Types](#6. WebApi Return Types)
      • [6.1 直接返回对象](#6.1 直接返回对象)
      • [6.2 返回多类型](#6.2 返回多类型)
    • [7. Action filter](#7. Action filter)
      • [7.1 创建filter](#7.1 创建filter)

项目地址

  • 教程作者:
  • 教程地址:
复制代码
  • 代码仓库地址:
复制代码
  • 所用到的框架和插件:

    webapi

一、WebAPI基础

1. 项目初始化

  1. 创建一个一个项目文件夹,并且在控制台输入

    dotnew webapi -n Restaurants.API --noopenapi -controllers

  2. 但是此时的项目是没有sln文件的,创建sln文件,但是这时候打开vs显示的是空项目

    dotnet new sln

  3. 将项目添加到vs里

    dotnet sln add ./Restaurants.API

1.1 创建简单的API

  • 在program.cs里使用routing中间件配置路由
1.1.1 get请求
  • 获取所有的shirts
cs 复制代码
app.MapGet("/shirts", () =>
{
    return "Reading all the shirts";
});
  • 根据ID获取一个
cs 复制代码
//2.get shirt by id 
app.MapGet("/shirts/{id}", (int id) =>
{
    return $"Reading shirt with ID: {id}";
});
1.1.2 post请求
app.MapPost("/shirts", () =>
{
    return "Creating a new shirt.";
});
1.1.3 put请求

更新

app.MapPut("/shirts/{id}", (int id) =>
{
    return $"Updating shirt with ID: {id}";
});
1.1.4 Delete请求

删除

app.MapDelete("/shirts/{id}", (int id) =>
{
    return $"Deleting shirt with ID: {id}";
});

1.2 webapi的流程

2.Controllers

2.1 创建一个shirts的Controller

  • 创建Controllers文件夹,在该文件夹下创建ShirtsController.cs文件
cs 复制代码
using Microsoft.AspNetCore.Mvc;

namespace WebAPIDemo.Controllers
{
    [ApiController]
    public class ShirtsController : ControllerBase
    {
        public string GetShirts()
        {
            return "Reading all the shirts";   
        }

        public string GetShirtById(int id)
        {
            return $"Reading shirt with ID: {id}";
        }

        public string CreateShirt()
        {
            return "Creating a new shirt.";
        }

        public string UpdateShirt() {
            return "Updating shirt with ID: {id}";
        }

        public string DeleteShirt(int id)
        {
            return $"Deleting shirt with ID: {id}";
        }

    }
}

3. Routing

3.1 使用和创建MapControllers

  1. Program.cs里添加rout的中间件
  1. 在Controller里,直接使用特性标记routing
cs 复制代码
using Microsoft.AspNetCore.Mvc;

namespace WebAPIDemo.Controllers
{
    [ApiController]
    public class ShirtsController : ControllerBase
    {
        [HttpGet("/shirts")]
        public string GetShirts()
        {
            return "Reading all the shirts";   
        }

        [HttpGet("/shirts/{id}")]
        public string GetShirtById(int id)
        {
            return $"Reading shirt with ID: {id}";
        }

        [HttpPost("/shirts")]
        public string CreateShirt()
        {
            return "Creating a new shirt.";
        }

        [HttpPut("/shirts/{id}")]
        public string UpdateShirt() {
            return "Updating shirt with ID: {id}";
        }

        [HttpDelete("/shirts/{id}")]
        public string DeleteShirt(int id)
        {
            return $"Deleting shirt with ID: {id}";
        }
    }
}

3.2 使用Routing的模板语言

  1. 在上面我们给每个Controller都使用一个路由,这样代码冗余,我们可以使用模板来指定rout;
  • 这样我们可以直接用过https://localhost:7232/shirts 进行访问shirts就是控制器的名称
  1. 如果我们想通过https://localhost:7232/api/shirts进行访问的话,修改模板routing

4. Mould Binding

将Http request和 Controller里的 parameter绑定起来

4.1 指定数据的来源

4.1.1 给Request请求添加
1. FromRoute
  • 指定这个参数必须是从https://localhost:7232/api/shirts/2/red从路由里来,如果不是,则报错
cs 复制代码
[HttpGet("{id}/{color}")]
public string GetShirtById(int id,[FromRoute]string color)
{
    return $"Reading shirt with ID: {id},color is {color}";
}
2. FromQuery
  • 必须通过QueryString的形式提供:https://localhost:7232/api/shirts/2?color=red

    [HttpGet("{id}/{color}")]
    public string GetShirtById(int id,[FromQuery]string color)
    {
    return $"Reading shirt with ID: {id},color is {color}";
    }

3. FromHeader
  • 必须通过请求头来传递,且Key是Name
cs 复制代码
[HttpGet("{id}/{color}")]
public string GetShirtById(int id,[FromHeader(Name="color")]string color)
{
    return $"Reading shirt with ID: {id},color is {color}";
}
4.1.2 给Post请求添加
  • 在webapp里创建一个新的文件夹Models,并且添加一个Shirts,cs
cs 复制代码
namespace WebAPIDemo.Models
{
    public class Shirt
    {
        public int ShirtId { get; set; }
        public string? Brand { get; set; }   
        public string? Color { get; set; }
        public int Size { get; set; }
        public string? Gender { get; set; }
        public double Price { get; set; }
    }
}
1. FromBody
  • 从请求体里来
cs 复制代码
[HttpPost]
public string CreateShirt([FromBody]Shirt shirt)
{
    return "Creating a new shirt.";
}
2. FromForm
  • 通过表格形式传递
cs 复制代码
[HttpPost]
public string CreateShirt([FromForm]Shirt shirt)
{
    return "Creating a new shirt.";
}

5. Mould Validation

5.1 添加Model Validation

  • Models/Shirts.cs类里添加验证,如果没有给出必须的参数,请求会报错400
cs 复制代码
using System.ComponentModel.DataAnnotations;

namespace WebAPIDemo.Models
{
    public class Shirt
    {
        [Required]
        public int ShirtId { get; set; }
        [Required]
        public string? Brand { get; set; }   
        public string? Color { get; set; }
        public int Size { get; set; }
        [Required]
        public string? Gender { get; set; }
        public double Price { get; set; }
    }
}

5.2 添加自定义的Validation

  1. Models文件夹里,添加Validations文件夹,并且添加文件Shirt_EnsureCorrectSizingAttribute.cs
cs 复制代码
using System.ComponentModel.DataAnnotations;
using WebAPIDemo.Models;

namespace WebApp.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.IsNullOrWhiteSpace(shirt.Gender))
            {
                if (shirt.Gender.Equals("men", StringComparison.OrdinalIgnoreCase) && shirt.Size < 8)
                {
                    return new ValidationResult("For men's shirts, the size has to be greater or equal to 8.");
                }
                else if (shirt.Gender.Equals("women", StringComparison.OrdinalIgnoreCase) && shirt.Size < 6)
                {
                    return new ValidationResult("For women's shirts, the size has to be greater or equal to 6.");
                }
            }

            return ValidationResult.Success;
        }
    }
}
  1. 我们验证的是Size,所以在Model里的Size添加我们自定义的Attribute
cs 复制代码
[Shirt_EnsureCorrectSizing]
public int Size { get; set; }

6. WebApi Return Types

6.1 直接返回对象

  • 创建一个List,存放所有的Shirt实例,返回一个Shirt类型

  • 通过id访问https://localhost:7232/api/shirts/1, 返回一个json

    {
    shirtId: 1,
    brand: "My Brand",
    color: "Blue",
    size: 10,
    gender: "Men",
    price: 30
    }

6.2 返回多类型

  • 如果返回多类型,就不能指定具体返回的类型,需要返回一个IActionResult
cs 复制代码
[HttpGet("{id}")]
public IActionResult GetShirtById(int id)
{
    if (id <= 0)
    {
        return BadRequest("Invalid shirt ID");
    }
    var shirt = shirts.FirstOrDefault(x => x.ShirtId == id);
    if( shirt == null)
    {
        return NotFound();
    }

    return Ok(shirt);
}

7. Action filter

  • 使用Action filter进行data validation

7.1 创建filter

  1. 创建Filters文件夹,并且创建Shirt_ValidateShirtId.cs类,并且添加对ShortId的验证
cs 复制代码
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using WebAPIDemo.Models.Repositories;


namespace WebAPIDemo.Filters
{
    public class Shirt_ValidateShirtIdFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);
            var shirtId = context.ActionArguments["id"] as int?;
            if (shirtId.HasValue)
            {
                if (shirtId.Value <= 0)
                {
                    context.ModelState.AddModelError("ShirtId", "ShirtId is invalid.");
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Status = StatusCodes.Status400BadRequest
                    };
                    context.Result = new BadRequestObjectResult(problemDetails);
                }
                else if (!ShirtRepository.ShirtExists(shirtId.Value))
                {
                    context.ModelState.AddModelError("ShirtId", "Shirt doesn't exist.");
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Status = StatusCodes.Status404NotFound
                    };
                    context.Result = new NotFoundObjectResult(problemDetails);
                }
            }
        }
    }
}
  1. 使用添加的filter,对 id进行验证
cs 复制代码
[HttpGet("{id}")]
[Shirt_ValidateShirtIdFilter]
public IActionResult GetShirtById(int id)
{
    return Ok(ShirtRepository.GetShirtById(id));
}
相关推荐
吃汤圆的抹香鲸2 小时前
Rider 安装包 绿色版 Win/Mac/Linux 适合.NET和游戏开发者使用 2025全栈开发终极指南:从零配置到企业级实战
linux·运维·windows·sql·游戏·macos·.net
学海无涯,行者无疆11 小时前
使用Jenkins实现Windows服务器下C#应用程序发布
windows·c#·jenkins·.net·cicd·自动发布·一键发布
喵叔哟15 小时前
7. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Ocelot 网关--路由
微服务·架构·.net
玩c#的小杜同学16 小时前
从“Switch-case“到“智能模式“:C#模式匹配的终极进化指南
开发语言·前端·c#·.net
MicrosoftReactor19 小时前
技术速递|.NET 9 网络优化
网络·.net
瓜皮弟子头很铁20 小时前
.net websocket 使用
网络·websocket·网络协议·.net
今晚打老虎z1 天前
MailKit: 在 .NET 中实现高效电子邮件发送与接收
git·github·.net
今晚打老虎z2 天前
SSH.NET: .NET 平台上的安全 Shell 库
安全·ssh·.net
今晚打老虎z2 天前
FFMpegCore:.NET 中进行音视频处理解决方案
.net·音视频
今晚打老虎z2 天前
FFmpeg.NET:.NET 平台上的音视频处理利器
.net