概述
项目是用的 NET6 webapi搭建一个前后端分离的后端管理框架,项目分为:表示层、业务层、数据访问层、数据存储层。
Common:公共组件层,存放一些公共的方法。Model:实体Model数据层,Enity文件夹中,存放的是项目的数据库表实体类,VeiwModel文件夹,是存放的DTO实体类,根据接口需要接收的数据和返回的数据。IRepository和 Repository :repository就是一个管理数据持久层的,它负责数据的CRUD。IServices和 Service:业务逻辑层,它主要是调用Repository层。
swagger
为了方便接口的查看和调试,本项目用swagger组件。
在.net core webapi 6.0是自带swagger功能的,以前在.net framework时代 swagger是要在项目下单独安装组件和配置后才具有的一个功能。项目启动后,在站点默认路径为:https://localhost:7182/swagger/index.html 这里就是swagger的首页。
NLog
1.Nuget 引入:
NLog
NLog.Web.AspNetCore
NLog.Database(写入数据库使用)
2.创建nlog.config
<?xml version="1.0" encoding="utf-8" ?> <!--internalLogLevel 记录Nlog自身日志级别,正式环境改为Error autoReload="true" nlog.config配置文件修改,程序将会重新读取配置文件,也就是自动再配置 --> <!--internalLogLevel="Error"--> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Info" internalLogFile="${basedir}/internal-nlog.txt"> <!-- 启用.net core的核心布局渲染器 --> <extensions> <add assembly="NLog.Web.AspNetCore" /> <!--写入数据库使用--> <!--<add assembly="NLog.Database" />--> </extensions> <!-- 写入日志的目标配置 --> <targets> <!-- all : write logs to file --> <target xsi:type="File" name="all" fileName="${basedir}/logs/all-${shortdate}.log" layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} " /> <!-- debug : write logs to file --> <target xsi:type="File" name="debug" fileName="${basedir}/logs/debug-${shortdate}.log" layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} " /> <!-- info : write logs to file --> <target xsi:type="File" name="info" fileName="${basedir}/logs/info-${shortdate}.log" layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} |url: ${aspnet-request-url} |action: ${aspnet-mvc-action}" /> <!-- error : write logs to file --> <target xsi:type="File" name="error" fileName="${basedir}/logs/error-${shortdate}.log" layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} |url: ${aspnet-request-url} |action: ${aspnet-mvc-action}" /> </targets> <!-- 映射规则 --> <rules> <!-- 将宿主生命周期消息输出到控制台目标,以更快地进行启动检测 --> <!--<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />--> <!-- 全部 --> <!--<logger name="*" minlevel="Trace" maxlevel="Fatal" writeTo="all" />--> <!-- 跳过不重要的微软日志 --> <logger name="Microsoft.*" maxlevel="Info" final="true" /> <logger name="System.Net.Http.*" maxlevel="Info" final="true" /> <!-- 调试 --> <logger name="*" levels="Trace,Debug" writeTo="debug" /> <!-- 信息、警告 --> <logger name="*" levels="Info,Warn" writeTo="info" /> <!-- 错误、致命错误 --> <logger name="*" levels="Error,Fatal" writeTo="error" /> </rules> </nlog>View Code
3.注入Nlog
using NLog; using NLog.Web; var logger = NLog.LogManager.Setup().LoadConfigurationFromFile("ConfigFile/NLog.config").GetCurrentClassLogger(); try { IConfiguration configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); var builder = WebApplication.CreateBuilder(args); builder.Services.AddSingleton(new AppSettingsHelper(configuration)); #region NLog配置 builder.Logging.ClearProviders(); builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); builder.Host.UseNLog(); #endregion // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseAuthorization(); app.MapControllers(); app.Run(); } catch (Exception ex) { logger.Error(ex, "由于异常而停止程序"); throw; } finally { LogManager.Shutdown(); }
4.使用
[HttpGet] public ActionResult<string> test(string username) { _logger.LogInformation("测试日志组件"); _logger.LogError($"LogError 方法"); return username + " ,你好!"; }
统一处理返回值和异常
1.定义统一的返回类
public enum ResultStatus { [Description("请求成功")] Success = 1, [Description("请求失败")] Fail = 0, [Description("请求异常")] Error = -1 } public class ResponseResult<TEntity> { /// <summary> /// 状态结果 /// </summary> public ResultStatus Status { get; set; } = ResultStatus.Success; private string? _msg; /// <summary> /// 消息描述 /// </summary> public string? Message { get { // 如果没有自定义的结果描述,则可以获取当前状态的描述 return !string.IsNullOrEmpty(_msg) ? _msg : EnumExtension.GetDescription(Status); } set { _msg = value; } } /// <summary> /// 返回结果 /// </summary> public TEntity Data { get; set; } /// <summary> /// 成功状态返回结果 /// </summary> /// <param name="result">返回的数据</param> /// <returns></returns> public static ResponseResult<TEntity> SuccessResult(TEntity data) { return new ResponseResult<TEntity> { Status = ResultStatus.Success, Data = data }; } /// <summary> /// 失败状态返回结果 /// </summary> /// <param name="code">状态码</param> /// <param name="msg">失败信息</param> /// <returns></returns> public static ResponseResult<TEntity> FailResult(string? msg = null) { return new ResponseResult<TEntity> { Status = ResultStatus.Fail, Message = msg }; } /// <summary> /// 异常状态返回结果 /// </summary> /// <param name="code">状态码</param> /// <param name="msg">异常信息</param> /// <returns></returns> public static ResponseResult<TEntity> ErrorResult(string? msg = null) { return new ResponseResult<TEntity> { Status = ResultStatus.Error, Message = msg }; } /// <summary> /// 自定义状态返回结果 /// </summary> /// <param name="status"></param> /// <param name="result"></param> /// <returns></returns> public static ResponseResult<TEntity> Result(ResultStatus status, TEntity data, string? msg = null) { return new ResponseResult<TEntity> { Status = status, Data = data, Message = msg }; } /// <summary> /// 隐式将TEntity转化为ResponseResult<TEntity> /// </summary> /// <param name="value"></param> public static implicit operator ResponseResult<TEntity>(TEntity value) { return new ResponseResult<TEntity> { Data = value }; } }
2.添加异常过滤器
public class ResultWrapperFilter : ActionFilterAttribute { public override void OnResultExecuting(ResultExecutingContext context) { var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var actionWrapper = controllerActionDescriptor?.MethodInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault(); var controllerWrapper = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault(); //如果包含NoWrapperAttribute则说明不需要对返回结果进行包装,直接返回原始值 if (actionWrapper != null || controllerWrapper != null) { return; } //根据实际需求进行具体实现 var rspResult = new ResponseResult<object>(); if (context.Result is ObjectResult) { var objectResult = context.Result as ObjectResult; if (objectResult?.Value == null) { rspResult.Status = ResultStatus.Fail; rspResult.Message = "未找到资源"; context.Result = new ObjectResult(rspResult); } else { //如果返回结果已经是ResponseResult<T>类型的则不需要进行再次包装了 if (objectResult.DeclaredType.IsGenericType && objectResult.DeclaredType?.GetGenericTypeDefinition() == typeof(ResponseResult<>)) { return; } rspResult.Data = objectResult.Value; context.Result = new ObjectResult(rspResult); } return; } } }
public class GlobalExceptionFilter : IExceptionFilter { private readonly ILogger<GlobalExceptionFilter> _logger; public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger) { _logger = logger; } public void OnException(ExceptionContext context) { //异常返回结果包装 var rspResult = ResponseResult<object>.ErrorResult(context.Exception.Message); //日志记录 _logger.LogError(context.Exception, context.Exception.Message); context.ExceptionHandled = true; context.Result = new InternalServerErrorObjectResult(rspResult); } public class InternalServerErrorObjectResult : ObjectResult { public InternalServerErrorObjectResult(object value) : base(value) { StatusCode = 500; } } }
3.注入
builder.Services.AddControllers(options => { options.Filters.Add<ResultWrapperFilter>(); options.Filters.Add<GlobalExceptionFilter>(); });
4.使用
public class TestController : ApiControllerBase { [HttpGet()] public ResponseResult<string> Get() { string datas = "测试统一返回消息"; //throw new Exception("测试异常是否被记录"); Convert.ToInt32("aaaaaaa"); return ResponseResult<string>.SuccessResult(datas) ; } }
Autofac
1.Nuget引入:
Autofac
Autofac.Extensions.DependencyInjection
2.定义Module,方便对注入服务进行管理
public class AutoFacManager : Autofac.Module { //重写Autofac管道Load方法,在这里注册注入 protected override void Load(ContainerBuilder builder) { //程序集注入业务服务 var IAppServices = Assembly.Load("TanYongJun.Repository"); var AppServices = Assembly.Load("TanYongJun.Service"); //根据名称约定(服务层的接口和实现均以Service结尾),实现服务接口和服务实现的依赖 builder.RegisterAssemblyTypes(IAppServices).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces(); builder.RegisterAssemblyTypes(AppServices).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces(); } }
注意:程序集的命名必须规范,否则可能读取不到 对应的数据集从而报错。
3.注入Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer<ContainerBuilder>(builder => { builder.RegisterModule(new AutoFacManager()); });
AutoMapper
1.Nuget引入:
AutoMapper
AutoMapper.Extensions.Microsoft.Dependencylnjection
2.定义Profile
public class CustomAutoMapper : Profile { /// <summary> /// 配置构造函数,用来创建关系映射 /// </summary> public CustomAutoMapper() {//这里写映射规则 //把 Student 映射到 StudentDTO CreateMap<Student, StudentDTO>(); CreateMap<SysUser, SysUserDTO>(); } }
3.注入
//AutoMapper builder.Services.AddAutoMapper(typeof(CustomAutoMapper));
4.使用
public class TestController : ApiControllerBase { private readonly IMapper _mapper; public TestController(IMapper mapper) { _mapper = mapper; } [HttpGet()] public ResponseResult<StudentDTO> Get() { var student = new Student() { Id = 1, RealName = "tanyongjun", Age = 21, Sex = 1, Remark = "" }; var studentDto = _mapper.Map<StudentDTO>(student); return ResponseResult<StudentDTO>.SuccessResult(studentDto); } }
EFCore
1.Nuget引入:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
2. 创建上下文类
public class EFCoreContext : DbContext { public EFCoreContext(DbContextOptions<EFCoreContext> options) : base(options) { } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new SysUserEntityTypeConfiguration()); #region 添加初始化数据 //modelBuilder.Entity<T>().HasData(new T { ..... }); #endregion base.OnModelCreating(modelBuilder); } }
3. 分别在IRepository和Repository项目下,新建IBaseRepository和BaseRepository,具体代码如下:
public interface IBaseRepository<TEntity> where TEntity : class { #region 添加 Task<TEntity> Add(TEntity entity); Task<int> Add(List<TEntity> listEntity); #endregion #region 修改 Task<bool> Update(TEntity entity); Task<bool> Update(TEntity model, params string[] propertyNames); Task<bool> Update(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames); #endregion #region 删除 Task<bool> Delete(TEntity entity); Task<bool> DeleteBy(Expression<Func<TEntity, bool>> delWhere); #endregion #region 查询 Task<TEntity> QueryBy(Expression<Func<TEntity, bool>> whereLambda); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereLambda); Task<List<TEntity>> Query(); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int top, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true); Task<PageModel<TEntity>> QueryPage<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true); #endregion #region 执行存储过程 Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text); Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text); #endregion ORTHER }
public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new() { private EFCoreContext _db; public BaseRepository(EFCoreContext mydbcontext) { this._db = mydbcontext as EFCoreContext; } #region 添加 /// <summary> /// 新增实体 /// </summary> /// <param name="entity">实体类</param> /// <returns></returns> public async Task<TEntity> Add(TEntity entity) { _db.Set<TEntity>().Add(entity); await _db.SaveChangesAsync(); return entity; } /// <summary> /// 批量新增实体 /// </summary> /// <param name="listEntity">实体集合</param> /// <returns>影响行数</returns> public async Task<int> Add(List<TEntity> listEntity) { await _db.Set<TEntity>().AddRangeAsync(listEntity); return await _db.SaveChangesAsync(); } #endregion #region 修改 /// <summary> /// 更新实体数据 /// </summary> /// <param name="entity"></param> /// <returns></returns> public async Task<bool> Update(TEntity entity) { _db.Set<TEntity>().Update(entity); return await _db.SaveChangesAsync() > 0; } /// <summary> /// 更新实体的指定字段 /// </summary> /// <param name="model"></param> /// <param name="propertyNames"></param> /// <returns></returns> public async Task<bool> Update(TEntity model, params string[] propertyNames) { EntityEntry entry = _db.Entry<TEntity>(model); entry.State = EntityState.Unchanged; foreach (string propertyName in propertyNames) { entry.Property(propertyName).IsModified = true; } return await _db.SaveChangesAsync() > 0; } /// <summary> /// 根据表达式查询出来的结果集,批量更新指定字段 /// </summary> /// <param name="model"></param> /// <param name="whereLambda"></param> /// <param name="modifiedPropertyNames"></param> /// <returns></returns> public async Task<bool> Update(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames) { List<TEntity> listModifing = _db.Set<TEntity>().Where(whereLambda).ToList(); Type t = typeof(TEntity); List<PropertyInfo> propertyInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList(); Dictionary<string, PropertyInfo> dicPropertys = new Dictionary<string, PropertyInfo>(); propertyInfos.ForEach(p => { if (modifiedPropertyNames.Contains(p.Name)) { dicPropertys.Add(p.Name, p); } }); foreach (string propertyName in modifiedPropertyNames) { if (dicPropertys.ContainsKey(propertyName)) { PropertyInfo proInfo = dicPropertys[propertyName]; object newValue = proInfo.GetValue(model, null); foreach (TEntity item in listModifing) { proInfo.SetValue(item, newValue, null); } } } return await _db.SaveChangesAsync() > 0; } #endregion #region 删除 /// <summary> /// 根据实体删除 /// </summary> /// <param name="entity"></param> /// <returns></returns> public async Task<bool> Delete(TEntity entity) { _db.Set<TEntity>().Attach(entity); _db.Set<TEntity>().Remove(entity); return await _db.SaveChangesAsync() > 0; } /// <summary> /// 根据表达式条件删除 /// </summary> /// <param name="delWhere"></param> /// <returns></returns> public async Task<bool> DeleteBy(Expression<Func<TEntity, bool>> delWhere) { List<TEntity> listDeleting = _db.Set<TEntity>().Where(delWhere).ToList(); listDeleting.ForEach(u => { _db.Set<TEntity>().Attach(u); _db.Set<TEntity>().Remove(u); }); return await _db.SaveChangesAsync() > 0; } #endregion #region 查询 /// <summary> /// 根据表达式查询,返回单个实体 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public async Task<TEntity> QueryBy(Expression<Func<TEntity, bool>> whereLambda) { return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().FirstOrDefaultAsync(); } /// <summary> /// 根据表达式查询,返回实体列表 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereLambda) { return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().ToListAsync(); } /// <summary> /// 返回实体所有列表 /// </summary> /// <returns></returns> public async Task<List<TEntity>> Query() { return await _db.Set<TEntity>().AsNoTracking().ToListAsync(); } #endregion #region 排序查询 /// <summary> /// 根据表达式查询,返回实体集合,并按指定排序 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="whereLambda"></param> /// <param name="orderLambda"></param> /// <param name="isAsc"></param> /// <returns></returns> public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true) { if (isAsc) { return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).AsNoTracking().ToListAsync(); } else { return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).AsNoTracking().ToListAsync(); } } /// <summary> /// 根据表达式查询,返回实体集合,并按指定排序返回指定行数 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="whereLambda"></param> /// <param name="top"></param> /// <param name="orderLambda"></param> /// <param name="isAsc"></param> /// <returns></returns> public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int top, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true) { if (isAsc) { return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).Take(top).AsNoTracking().ToListAsync(); } else { return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).Take(top).AsNoTracking().ToListAsync(); } } #endregion #region 分页查询 /// <summary> /// 按表达式分页查询,并按指定排序,返回实体集合 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="whereLambda"></param> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="orderByLambda"></param> /// <param name="isAsc"></param> /// <returns></returns> public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true) { if (isAsc) { return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync(); } else { return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync(); } } /// <summary> /// 按表达式分页查询,并按指定排序,返回分页实体 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="whereLambda"></param> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="orderByLambda"></param> /// <param name="isAsc"></param> /// <returns></returns> public async Task<PageModel<TEntity>> QueryPage<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true) { var rowCount = await _db.Set<TEntity>().Where(whereLambda).CountAsync(); int pageCount = (int)(Math.Ceiling(rowCount/ Convert.ToDouble( pageSize))); List<TEntity> list; if (isAsc) { list = await _db.Set<TEntity>().OrderBy(orderByLambda).Where(whereLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync(); } else { list = await _db.Set<TEntity>().OrderByDescending(orderByLambda).Where(whereLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync(); } return new PageModel<TEntity>() { DataCount = rowCount, PageCount = pageCount, Page = pageIndex, PageSize = pageSize, DataList = list }; } #endregion #region 存储过程 /// <summary> /// 执行存储过程 exec Proc_ @name,返回实体集合 /// </summary> /// <param name="sql"></param> /// <param name="parms"></param> /// <param name="cmdType"></param> /// <returns></returns> public async Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text) { if (cmdType == CommandType.StoredProcedure) { StringBuilder paraNames = new StringBuilder(); foreach (var sqlPara in parms) { paraNames.Append($" @{sqlPara},"); } sql = paraNames.Length > 0 ? $"exec {sql} {paraNames.ToString().Trim(',')}" : $"exec {sql} "; } return await _db.Set<TEntity>().FromSqlRaw(sql).ToListAsync(); } /// <summary> /// 执行存储过程 exec Proc_ @name,返回影响行数 /// </summary> /// <param name="sql"></param> /// <param name="parms"></param> /// <param name="cmdType"></param> /// <returns></returns> public async Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text) { if (cmdType == CommandType.StoredProcedure) { StringBuilder paraNames = new StringBuilder(); foreach (var sqlPara in parms) { paraNames.Append($" @{sqlPara},"); } sql = paraNames.Length > 0 ? $"exec {sql} {paraNames.ToString().Trim(',')}" : $"exec {sql} "; } int ret = await _db.Database.ExecuteSqlRawAsync(sql, parms.ToArray()); return 0; } #endregion }
BaseRepository中主要是实现了一些基础的CURD操作,并且封装了一些常用的数据库操作。
跨域
appsettings.json
appsettings.json中主要是存放一些项目中配置参数,和以前的webconfig文件。为了方便这里写一个读取的公用类。
1.Nuget 引入:
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.Configuration.Binder.
using Microsoft.Extensions.Configuration; namespace TanYongJun.Common { /// <summary> /// appsettings.json操作类 /// </summary> public class AppSettingsHelper { private static IConfiguration? _config; public AppSettingsHelper(IConfiguration configuration) { _config = configuration; } /// <summary> /// 读取指定节点的字符串 /// </summary> /// <param name="sessions"></param> /// <returns></returns> public static string ReadAppSettings(params string[] sessions) { try { if (sessions.Any()) { return _config[string.Join(":", sessions)]; } } catch { return ""; } return ""; } /// <summary> /// 读取实体信息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="session"></param> /// <returns></returns> public static List<T> ReadAppSettings<T>(params string[] session) { List<T> list = new List<T>(); _config.Bind(string.Join(":", session), list); return list; } } }
2.注入
3.使用:
标签:WebApi,Vue,return,db,whereLambda,Task,NET6,Expression,public From: https://www.cnblogs.com/tanyongjun/p/17067419.html