Bootstrap

WebApi配置Swagger、Serilog、NewtonsoftJson、Sqlsugar、依赖注入框架Autofac、MD5加密

项目准备

1、创建WebApi项目

配置Swagger、Serilog、NewtonsoftJson

NewtonsoftJson

引入Microsoft.AspNetCore.Mvc.NewtonsoftJson的包

编写配置代码,在启动类中使用Program

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

Swagger

使用扩展的方式进行swagger注释的配置

using System.Reflection;
using Microsoft.OpenApi.Models;
using noteVersion.utils;

namespace noteVersion.ExtTool;

public static class SwaggerExt
{
    /// <summary>
    /// 添加Swagger扩展
    /// </summary>
    public static void AddSwaggerExt(this IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
        {
            /*版本控制*/
            typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>
            {
                c.SwaggerDoc(version, new OpenApiInfo { Title = "NoteVersion Api", Version = version });
            });
            /*添加注释*/
            var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
        });
    }
    /// <summary>
    /// 使用Swagger扩展
    /// </summary>
    public static void UseSwaggerExt(this WebApplication application)
    {
        application.UseSwagger();
        application.UseSwaggerUI(c =>
        {
            foreach (var item in typeof(ApiVersion).GetEnumNames())
            {
                c.SwaggerEndpoint($"/swagger/{item}/swagger.json", $"WebAread Api {item}版本");
            }
        });
    }
}

在启动类中使用Program

//注册扩展
builder.Services.AddSwaggerExt();
//使用扩展
app.UseSwaggerExt();

在项目的属性文件里配置开启文档生成projrct.csproj

<GenerateDocumentationFile>True</GenerateDocumentationFile>

Serilog

下载Serilog.AspNetCore

编写log扩展(依赖注入方式使用插件,还有配置文件方式等)

using Serilog;
using Serilog.Events;

namespace noteVersion.ExtTool;

public static class SerilogExt
{
    public static void AddSerilogExt(this WebApplicationBuilder builder)
    {
        builder.Services.AddSerilog(cfg =>
        {
            cfg.MinimumLevel.Information()
                .WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Information)
                .WriteTo.File("Logs/Errors/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error);
        });
    }
}

在Program里注册Serilog

builder.AddSerilogExt();

使用在Controller类里

using Microsoft.AspNetCore.Mvc;

namespace noteVersion.Controllers;
/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;
    private int a = 27;

    public UserController(ILogger<UserController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 测试
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> Test()
    {
        _logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试{a}");
        return Ok("测试成功");
    }
}

使用ORM框架SqlSugar

下载SqlSugarCore

编写json连接字符串在appsettings.json

 "SqlSugar": {
    "ConnectString": "server = 127.0.0.1; Database = test; Uid = root; Pwd = root; AllowLoadLocalInfile = true;"
  },

创建Helper类库进行sqlsugar配置

由于Sqlsugar官方网站建议不要让SqlClient进行上下文的联动,所以一个块里new一个Sqlclient。

于是我使用传参的方式进行实例化时的配置。

using Microsoft.Extensions.Configuration;
using SqlSugar;

namespace WebReadSite.DataAccess;
public class DbContext
{
    private readonly IConfiguration _configuration;
    private SqlSugarClient _dbClient;

    public DbContext(IConfiguration configuration)
    {
        _configuration = configuration;
        InitializeDatabase();
    }

    private void InitializeDatabase()
    {
        string connectionString = _configuration["SqlSugar:ConnectString"];
        
        _dbClient = new SqlSugarClient(new ConnectionConfig()
        {
            ConnectionString = connectionString,
            DbType = DbType.MySql,
            IsAutoCloseConnection = true
        });
    }

    public SqlSugarClient GetDbClient()
    {
        return _dbClient;
    }
}

创建Models类库进行数据实体的配置

using SqlSugar;

namespace Models;

[SugarTable(tableName: "Users")]
public class User
{
    [SugarColumn(IsPrimaryKey = true)] 
    public string USERID { get; set; }
    public string USERNAME { get; set; }
    public string EMAIL { get; set; }
    public string PASSWORD { get; set; }
    public DateTime CREATEAT { get; set; }
    public DateTime UPDATEAT { get; set; }
}

Controller类中使用Sqlsugar

使用IConfiguration读取Json配置,在方法里使用SqlClient执行插入

using Microsoft.AspNetCore.Mvc;
using Models;
using SqlSugar;
using WebReadSite.DataAccess;

namespace noteVersion.Controllers;
/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;
    
    IConfiguration configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .Build();
 

    public UserController(ILogger<UserController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 测试
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> Test()
    {
        DbContext dbContext = new DbContext(configuration);
        SqlSugarClient dbClient = dbContext.GetDbClient();
        dbClient.Insertable(new User() { USERID = Guid.NewGuid().ToString(), USERNAME = "jack" }).ExecuteCommand();
        
        _logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试");
        return Ok("测试成功");
    }
}

创建Service类库构成MVC框架

创建IServiceService类库

使用AutoFac进行依赖注入

安装Autofac包和Autofac.Extensions.DependencyInjection

创建Autofac扩展

using System.Reflection;
using Autofac;
using Autofac.Extensions.DependencyInjection;

namespace noteVersion.ExtTool;

public static class AutofacExt
{
    /// <summary>
    /// Autofac使用dll注入
    /// </summary>
    /// <param name="builder"></param>
    /// <exception cref="Exception"></exception>
    public static void AddAutofac(this WebApplicationBuilder builder)
    {
        var basePath = AppContext.BaseDirectory;
        var servicesDllFile = Path.Combine(basePath, "noteVersion.Service.dll"); //服务层
        if (!(File.Exists(servicesDllFile) && File.Exists(servicesDllFile)))
        {
            throw new Exception("service.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。");
        }
        //使用IOC工厂类
        builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
        // 获取 Repository.dll 程序集服务,并注册
        var assemblysRepository = Assembly.LoadFrom(servicesDllFile);
        builder.Host.ConfigureContainer<ContainerBuilder>(build =>
        {
            build.RegisterAssemblyTypes(assemblysRepository)
                .AsImplementedInterfaces()
                .InstancePerDependency();
        });
    } 
}

Program进行注册

builder.AddAutofac();

使用在Controller中

注入了IUserManager类

using Microsoft.AspNetCore.Mvc;
using Models;
using Service;
using IService;
using WebReadSite.DataAccess;

namespace noteVersion.Controllers;

/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;
    private readonly IUserManager _userManager;

    private readonly IConfiguration _configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .Build();

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="userManager"></param>
    public UserController(ILogger<UserController> logger,IUserManager userManager)
    {
        _logger = logger;
        _userManager = userManager;
    }

    /// <summary>
    /// 测试
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> Test()
    {
        var dbContext = new DbContext(_configuration);
        var dbClient = dbContext.GetDbClient();
        await dbClient.Insertable(new User() { USERID = Guid.NewGuid().ToString(), USERNAME = "jack" }).ExecuteCommandAsync();

        _logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试");
        return Ok("测试成功");
    }

    /// <summary>
    /// 添加用户
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> AddUser(string name, string email, string password)
    {
        try
        {
            var result =await _userManager.CreateUser(name, email, password);
            return Ok(result);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            return BadRequest(e.Message);
        }
       
    }
}

创建用户登录接口

  1. 用户管理(User Management)
    • 这个模块负责用户账户的创建、修改和删除操作。它通常包括注册新用户、更新用户信息、重置密码等功能。

Service类库下的UserManager

using System.Runtime.InteropServices.JavaScript;
using IService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Models;
using WebReadSite.DataAccess;

namespace Service;

public class UserManager : IUserManager
{
    private readonly ILogger<UserManager> _logger;

    IConfiguration configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .Build();

    public UserManager(ILogger<UserManager> logger)
    {
        _logger = logger;
    }

    public UserManager()
    {
    }

    /// <summary>
    /// 创建用户
    /// </summary>
    public async Task<int> CreateUser(string name, string email, string password)
    {
        var dbContext = new DbContext(configuration);
        var dbClient = dbContext.GetDbClient();
        try
        {
            await dbClient.BeginTranAsync();
            var result = await dbClient.Insertable(new User()
            {
                USERID = Guid.NewGuid().ToString(),
                USERNAME = name, EMAIL = email, PASSWORD = password,
                CREATEAT = DateTime.Now
            }).ExecuteCommandAsync();

            await dbClient.CommitTranAsync();
            return result;
        }
        catch (Exception e)
        {
            _logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");
            await dbClient.RollbackTranAsync(); //数据回滚
            throw new Exception("创建用户失败");
        }

    }


    public void UpdateUser()
    {
        try
        {
        }
        catch (Exception e)
        {
            _logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");

            throw;
        }
    }

    public void DeleteUser()
    {
        try
        {
        }
        catch (Exception e)
        {
            _logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");

            throw;
        }
    }
}

在Controller中使用(同上上)

 /// <summary>
    /// 添加用户
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> AddUser(string name, string email, string password)
    {
        try
        {
            var result =await _userManager.CreateUser(name, email, password);
            return Ok(result);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            return BadRequest(e.Message);
        }
    }

添加用户时进行安全防护

使用Post传输且用body传输

/// <summary>
    /// 添加用户
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<IActionResult> AddUser(UserInfo userInfo)
    {
        try
        {
            var result =await _userManager.CreateUser(userInfo.name, userInfo.email, userInfo.password);
            return Ok(result);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            return BadRequest(e.Message);
        }
       
    }

*添加MD5加密,之后保存进数据库UserManager*类

 /// <summary>
    /// 创建用户
    /// </summary>
    public async Task<int> CreateUser(string name, string email, string password)
    {
        var dbContext = new DbContext(configuration);
        var dbClient = dbContext.GetDbClient();
        try
        {
            await dbClient.BeginTranAsync();
            var result = await dbClient.Insertable(new User()
            {
                USERID = Guid.NewGuid().ToString(),
                USERNAME = name, EMAIL = email, PASSWORD = GetMD5Encryption(password),
                CREATEAT = DateTime.Now
            }).ExecuteCommandAsync();
            
            await dbClient.CommitTranAsync();
            return result;
        }
        catch (Exception e)
        {
            _logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");
            await dbClient.RollbackTranAsync(); //数据回滚
            throw new Exception("创建用户失败");
        }

    } 

/// <summary>
    /// 获取MD5算法字符串
    /// </summary>
    /// <param name="passWord"></param>
    /// <returns></returns>
    public string GetMD5Encryption(string passWord)
    {
        // 创建一个 MD5 实例
        using (MD5 md5Hash = MD5.Create())
        {
            // 将输入字符串转换为字节数组,并计算哈希值
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(passWord));
            // 创建一个 StringBuilder 来收集字节并创建字符串
            StringBuilder sBuilder = new StringBuilder();
            // 将每个字节的哈希值转换为十六进制并追加到字符串构建器
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2")); // 使用 "x2" 格式化符将每个字节转换为十六进制
            }
            // 返回十六进制字符串
            return sBuilder.ToString();
        }
    }

TODO:用户登录后进行JWT校验,校验通过后进行单点登录,之后进行文件的上传、文件列表的获取

;