文章目录
项目准备
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框架
创建IService
与Service
类库
使用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);
}
}
}
创建用户登录接口
- 用户管理(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校验,校验通过后进行单点登录,之后进行文件的上传、文件列表的获取