基于.NET6搭建WebAPI项目

创建项目

 点击运行后自动打开浏览器,看到如下信息:

系统启动日志如下:

 修改返回数据的时间格式

此数据对用户不友好。

nuget安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson

 

安装成功:

 只需要在Program.cs 文件下添加几行代码
找到builder.Services.AddControllers()

 

代码如下:

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //格式化时间
    });

 测试结果如下:

开启Swagger 注释

打开Xml文件生成,右键项目进入属性设置:

取消未进行注释而进行提示的警告:

然后Progarm.cs 添加如下代码 

 

代码如下:

builder.Services.AddSwaggerGen(options => 
{
    //获取xml文件名称
    var xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    //包含注释,第二个参数表示是否显示控制器注释
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFileName), true);
});

 在测试控制器中添加注释进行测试:

测试ok:

 添加版本控制:

首先创建一个枚举类:

代码:

namespace IIoT.WebAPI
{
    /// <summary>
    /// API版本枚举
    /// </summary>
    public enum APIVersion
    {
        /// <summary>
        /// v1版本
        /// </summary>
        v1,
        /// <summary>
        /// v2版本
        /// </summary>
        v2,
    }
}

然后Progarm.cs 添加如下代码 :

//显示多个文档
    typeof(APIVersion).GetEnumNames().ToList().ForEach(version =>
    {
        //添加文档介绍
        options.SwaggerDoc(version, new OpenApiInfo
        {
            Title = "海云物联项目",
            Version = version.ToString(),
            Description = $"海云物联项目:{version}版本"
        });
    });

 还有如下代码:

 //版本切换
    app.UseSwaggerUI(options =>
    {
        typeof(APIVersion).GetEnumNames().ToList().ForEach(version =>
        {
            options.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"版本选择:{version}");
        });
    });

在测试控制器方法中添加版本控制特性:

 运行项目进行测试:

引入SqlSugar 

官网文档:

SqlSugar ORM 5.X 官网 、文档、教程 - SqlSugar 5x - .NET果糖网https://www.donet5.com/Home/Doc

nuget安装SqlSugarCore :

注入IoC容器:

使用第二种方式进行注入:

创建扩展类:

创建目录Extensions:

代码如下:

using SqlSugar;

namespace IIoT.WebAPI.Extensions
{
    /// <summary>
    /// Sqlsugar扩展类
    /// </summary>
    public static class SqlsugarSetup
    {
        public static void AddSqlsugarSetup(this IServiceCollection services, IConfiguration configuration, string dbName = "db_master")
        {
            SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
            {
                DbType = DbType.MySql, //数据库类型
                ConnectionString = configuration.GetConnectionString(dbName), //连接字符串
                IsAutoCloseConnection = true, //是否自动关闭连接
            },
            db =>
            {
                //单例参数配置,所有上下文生效
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql); //输出sql
                    Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value))); //查看执行的sql语句
                };
            });
            services.AddSingleton<ISqlSugarClient>(sqlSugar); //这边是SqlSugarScope用AddSingleton
        }
    }
}

 

配置数据库连接字符串:

"ConnectionStrings": {
    "db_master": "server=127.0.0.1;Database=test_sqlsugar;Uid=root;Pwd=ghy@123;Allow User Variables=True;"
  }

 创建一个空的数据库:

导入sql脚本:

包含如下表:

基于官方提供的代码生成器生成实体类:

 配置数据库:

验证是否成功

有效链接会显示成 true ,库已建会显示成true  那么就代表配置成功了,如果不成功请手动建库和检查字符串

点击菜单

 选择数据库:

点击导入:

导入表:

 导入完成:

 导入完成我们可以点预览或者生成 去生成代码 

生成的文件如下:

将其拷贝到models文件夹下面:

 创建控制器:用于管理岗位信息。

 最好还是选择第二个:

运行测试:

 构建仓储模式

创建Repositories文件夹:

创建公共仓储类:

代码如下:

using SqlSugar;

namespace IIoT.WebAPI.Repositories
{
    /// <summary>
    /// 公共仓储类
    /// </summary>

    public class BaseRepository<T> : SimpleClient<T> where T : class, new() //固定写法
    {
        public BaseRepository(ISqlSugarClient context = null) : base(context) //注意这里要有默认值null
        {

            base.Context = context; //ioc注入的对象
        }

        /// <summary>
        /// 扩展方法,自带方法不能满足的时候可以添加新方法
        /// </summary>
        /// <returns></returns>
        public List<T> CommQuery(string json)
        {
            //base.Context.Queryable<T>().ToList();可以拿到SqlSugarClient 做复杂操作
            return null;
        }

    }
}

创建岗位信息仓储类:

SysPostRepository:

继承的时候指定类型为SysPost,那么SysPostRepository的所有操作都是针对SysPost表的:

代码如下:

using IIoT.WebAPI.Models;

namespace IIoT.WebAPI.Repositories
{
    /// <summary>
    /// 岗位仓储类
    /// </summary>
    public class SysPostRepository: BaseRepository<SysPost>
    {
        /// <summary>
        /// 查询所有岗位信息
        /// </summary>
        /// <returns></returns>
        public List<SysPost> GetSysPosts()
        {
            return base.Context.Queryable<SysPost>().ToList();
        }
    }
}

控制器中进行相关IoC注入操作:

注意:上述修改有错误,只需要创建公共仓储类即可。

using SqlSugar;

namespace IIoT.WebAPI.Repositories
{
    /// <summary>
    /// 公共仓储类
    /// </summary>

    public class Repository<T> : SimpleClient<T> where T : class, new() //固定写法
    {
        public Repository(ISqlSugarClient context = null) : base(context) //注意这里要有默认值null
        {

            base.Context = context; //ioc注入的对象
        }

        /// <summary>
        /// 扩展方法,自带方法不能满足的时候可以添加新方法
        /// </summary>
        /// <returns></returns>
        public List<T> CommQuery(string json)
        {
            //base.Context.Queryable<T>().ToList();可以拿到SqlSugarClient 做复杂操作
            return null;
        }

    }
}

然后修改Program.cs文件:

运行测试:

 

异步创建webapi:

控制器代码如下:

[HttpGet("{id}")]
        public Task<SysPost> GetSysPostById(int id)
        {
            return this._sysPostRepository.GetByIdAsync(id);
            //return "value";
        }

非常简介。

添加FluentValidation 数据校验

Nuget 安装FluentValidation.AspNetCore:

依赖注入:

代码如下:

//注入数据校验
builder.Services.AddFluentValidation(option =>
{
    option.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
});

 创建Validations文件夹:

创建实体类对应校验类:

using FluentValidation;
using IIoT.WebAPI.Models;

namespace IIoT.WebAPI.Validations
{
    public class SysPostValidation: AbstractValidator<SysPost>
    {
        public SysPostValidation()
        {
            //对每个字段进行单独校验
            RuleFor(it=>it.PostName)
                .NotEmpty().WithMessage("岗位名称不能为空!");
        }
    }
}

测试情况:

 

跨域问题处理 

在主文件中进行配置:

//注入跨域
builder.Services.AddCors(c =>
{
    c.AddPolicy("Cors", policy =>
    {
        policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
    });
});
app.UseCors("Cors"); //配置跨域组件,注意添加的顺序

 JWT认证

创建Common文件夹:83687988

创建JwtHelper类:

using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace IIoT.WebAPI.Common
{
    /// <summary>
    /// Jwt帮助类
    /// </summary>
    public static class JwtHelper
    {
        /// <summary>
        /// 创建Jwt字符串
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string CreateJwt(TokenModelJwt model)
        {
            var claims = new List<Claim>
            {
                new Claim("UserId",model.UserId.ToString()), //保存用户Id
                new Claim("UserName",model.UserName), //保存用户名称
                new Claim("Role", model.Role) //保存用户角色
            };

            /*
            //秘钥 分开的写法
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(model.Secret));
            var creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(model.Secret)), SecurityAlgorithms.HmacSha256);
            */

            var jwt = new JwtSecurityToken(
                issuer: model.Issuer,
                audience: model.Audience,
                expires: DateTime.Now.AddSeconds(model.Expires),
                signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(model.Secret)), 
                SecurityAlgorithms.HmacSha256),
                claims: claims
            );

            /* 分开的写法
            var jwtHandler = new JwtSecurityTokenHandler();
            var token = new JwtSecurityTokenHandler().WriteToken(jwt);
            */

            return new JwtSecurityTokenHandler().WriteToken(jwt);
        }

        /// <summary>
        /// 解析Jwt字符串并转换为TokenModelJwt对象
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static TokenModelJwt SerializeJwt(string jwtStr)
        {
            //解析token
            var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(jwtStr);
            var tokenJwt = JsonConvert.DeserializeObject<TokenModelJwt>(jwtToken.Payload.SerializeToJson());
            return tokenJwt;
        }

    }
    
    /// <summary>
    /// 令牌对象
    /// </summary>
    public class TokenModelJwt
    {
        /// <summary>
        /// 用户Id
        /// </summary>
        public int UserId { get; set; }
        /// <summary>
        /// 用户名称
        /// </summary>
        public string UserName { get; set; }
        /// <summary>
        /// 发行人
        /// </summary>
        public string Issuer { get; set; }
        /// <summary>
        /// 观众
        /// </summary>
        public string Audience { get; set; }
        /// <summary>
        /// 秘钥
        /// </summary>
        public string Secret { get; set; }
        /// <summary>
        /// 过期时间
        /// </summary>
        public int Expires { get; set; }
        /// <summary>
        /// 角色
        /// </summary>
        public string Role { get; set; }
    }
}

配置文件配置:

 "Jwt": {
    "Secret": "asdasfdgsdgtrhythyjyukjtyujgfjgfhjyjr", //不要太短,16位+
    "Issuer": "haiyun",
    "Audience": "haiyun"
  }

 

创建Jwt控制器:

using IIoT.WebAPI.Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace IIoT.WebAPI.Controllers
{
    /// <summary>
    /// Jwt控制器
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class JwtController : ControllerBase
    {
        private readonly IConfiguration _configuration;

        public JwtController(IConfiguration configuration)
        {
            this._configuration = configuration;
        }

        /// <summary>
        /// 获取Jwt字符串
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public string CreateToken()
        {
            var tokenModel = this._configuration.GetSection("Jwt").Get<TokenModelJwt>(); //获取TokenModelJwt对象
            tokenModel.UserName = "ghy";
            tokenModel.UserId = 1;
            tokenModel.Role = "Admin";
            tokenModel.Expires = 60 * 30; //过期时间默认设置为30min
            return JwtHelper.CreateJwt(tokenModel);
        }
    }
}

 

 运行测试:

swagger添加jwt配置:

然后再Promgram.cs 加上Jwt的验证:

注意jwt部分的内容相对复杂,这里不再做介绍.

  • 26
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
在C# WebApi项目实践中,可以采用ASP.NET Core 3.1 WebApi的干净体系结构来实现。您可以使用开源的BoilerPlate模板来创建一个干净的体系结构。通过这个模板,您可以获得ASP.NET Core的一些基础功能,如身份验证和授权管理。 在控制器中,您可以使用HttpPost和HttpGet属性来定义一个既支持POST请求又支持GET请求的方法。例如,您可以在控制器中添加一个CheckUserName方法来检查用户名是否已经注册。该方法通过调用UserInfoGetCount方法来查询是否存在该用户,然后根据查询结果返回相应的响应消息。 在WebApi项目中的appsettings.json文件可以修改应用程序和身份验证的连接字符串,以适应您的具体需求。 在构建WebApi项目时,您可以注意到它与MVC非常相似。首先,您可以修改路由以添加action,这样可以更方便地处理请求。在App_start文件中,WebApi使用没有action的路由规则,您可以根据需要修改路由规则使其与MVC的路由规则相同。 通过以上的实践,您可以构建出一个基于C#的WebApi项目,并实现一些常用的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CleanArchitecture.WebApi:ASP.NET Core 3.1 WebAPI的Clean Architecture的实现。建立时考虑了松散耦合的...](https://download.csdn.net/download/weixin_42097189/15896591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C#搭建一个简单的web api项目](https://blog.csdn.net/hdy14/article/details/88187455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值