概述

项目是用的 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>

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.使用:

.NET6+WebApi+Vue 前后端分离后台管理系统(一)的更多相关文章

  1. 前后端分离后台管理系统 Gfast v3.0 全新发布

    GFast V3.0 平台简介 基于全新Go Frame 2.0+Vue3+Element Plus开发的全栈前后端分离的管理系统 前端采用vue-next-admin .Vue.Element UI ...

  2. ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

    前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...

  3. 解决Django+Vue前后端分离的跨域问题及关闭csrf验证

      前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道   在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...

  4. Flask + vue 前后端分离的 二手书App

    一个Flask + vue 前后端分离的 二手书App 效果展示: https://blog.csdn.net/qq_42239520/article/details/88534955 所用技术清单 ...

  5. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  6. 两个开源的 Spring Boot + Vue 前后端分离项目

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  7. WebAPI 实现前后端分离的示例

    转自:http://www.aspku.com/kaifa/net/298780.html 随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数.全栈工程师的压力越来越大. 现在的前端的框架, ...

  8. beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)

    具体过程就不说,是搞这个的自然会动,只把关键代码贴出来. beego和vue前后端分离开发,beego承载vue前端分离页面部署 // landv.cnblogs.com //没有授权转载我的内容,再 ...

  9. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题

    原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...

  10. Springboot+vue前后端分离项目,poi导出excel提供用户下载的解决方案

    因为我们做的是前后端分离项目 无法采用response.write直接将文件流写出 我们采用阿里云oss 进行保存 再返回的结果对象里面保存我们的文件地址 废话不多说,上代码 Springboot 第 ...

随机推荐

  1. 基于Unet+opencv实现天空对象的分割、替换和美化

           传统图像处理算法进行"天空分割"存在精度问题且调参复杂,无法很好地应对云雾.阴霾等情况:本篇文章分享的"基于Unet+opencv实现天空对象的分割.替换和 ...

  2. CH32V307以太网(芯片内部10M)-针对新固件的Lib库

    沁恒的CH32V307网络库在前段时间做了一个更新,相对于以前的Lib,主要的功能没有什么特别大的变化,但是底层的一些操作仔细看的话,还是不少的区别的. 首先,官方提供的例程,工程结构以及头文件优一些 ...

  3. 【Linux】TCS34725 颜色传感器设备驱动

    一.概述 此笔记主要是学习 Linux 中的 I2C 驱动,顺便验证一下 TCS34725 传感器的使用,主要内容还是程序记录,方便编写其他 I2C 设备驱动时做参考,所以关于 TCS34725 这里 ...

  4. (Java)设计模式:结构型

    前言 这篇博文续接的是 UML建模.设计原则.创建型设计模式.行为型设计模式,有兴趣的可以看一下 3.3.结构型 这些设计模式关注类和对象的组合.将类和对象组合在一起,从而形成更大的结构 * 3.3. ...

  5. group by 语句怎么优化?

    一.一个简单使用示例 我这里创建一张订单表 CREATE TABLE `order_info` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', `or ...

  6. Linux的串口非标准波特率设置更改

    用的是全志的R528 SDK,Linux内核是5.4,新增加一个250000的非标准波特率 参考网络大神文档,实践并记录宝贵的经验. 方法: 1.修改内核的/include/uapi/asm-gene ...

  7. win32com操作word 第三集:Range精讲(一)

    本课程<win32com操作word API精讲&项目实战>,本公众号以文字分享为主,B站与视频号则发布视频分享,ID均为:一灯编程 本集开始,将会深入Document接口.打开或 ...

  8. VUE assets里的scss没有引用会被打包进代码里,本地代码和打包后的代码样式不一致解决办法

    1.打包部署后,发现样式和本地运行时候代码不一致 经过排查发现 这个路径的文件被打包进去了,但是我并没有引用这个文件啊啊啊啊啊a~~~~ src\assets\webgl-assets\scss\st ...

  9. 如何让Java编译器帮你写代码

    作者:京东零售 刘世杰 导读 本文结合京东监控埋点场景,对解决样板代码的技术选型方案进行分析,给出最终解决方案后,结合理论和实践进一步展开.通过关注文中的技术分析过程和技术场景,读者可收获一种样板代码 ...

  10. Vue 07 js方法Object.defineProperty

    1 描述 该方法允许精确地添加或修改对象的属性.可以对已有的属性进行获取及修改,也可以添加新的属性并进行操作. 2 方法参数 Object.defineProperty(操作的对象,添加的属性的名称, ...