概述

项目是用的 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. AcWing342. 道路与航线

    原题链接 解题思路 这题用\(SPFA\)会被卡,所以我们不能用\(SPFA\) 但是观察数据我们可以发现对于道路,\(0≤C_i≤10^{5}\) 所以对于每个连通块(内部不存在航线),我们可以用\ ...

  2. python与数值计算环境安装

    数值计算的编程的软件很多种,也见过一些编程绘图软件的对比. 利用Python进行数值计算,需要用到numpy(矩阵) ,scipy(公式符号), matplotlib(绘图)这些工具包. 1.Linu ...

  3. k8s本地联调工具kt-connect

    1.Kt Connect简介 KT Connect ( Kubernetes Developer Tool ) 是轻量级的面向 Kubernetes 用户的开发测试环境治理辅助工具.其核心是通过建立本 ...

  4. Auto-Job任务调度框架

    Auto-Job 任务调度框架 一.背景 生活中,业务上我们会碰到很多有关作业调度的场景,如每周五十二点发放优惠券.或者每天凌晨进行缓存预热.亦或每月定期从第三方系统抽数等等,Spring和java目 ...

  5. Redis-03 Redis事务

    需要特别注意,Redis 的命令是原子性的,而 Redis 的事务是非原子性的 事务相关命令 MULTI 命令 开启事务命令,Redis将操作命令逐个放到队列中,根据EXEC命令来原子化执行命令 EX ...

  6. python进阶之路2——解释器软件安装

    内容概要 计算机五大组成部分 计算机三大核心硬件 操作系统 编程与编程语言 编程语言发展史 编程语言的分类 python解释器下载与安装 python解释器多版本共存 pycharm安装 计算机五大组 ...

  7. JavaScript 图像压缩

    JavaScript 可以使用类似于 canvas 和 web workers 来实现图像压缩. 使用 canvas,可以将图像绘制到 canvas 上,然后使用 canvas 提供的 toBlob( ...

  8. Python面向对象(上)

    Python面向对象(上) python是一门面向对象的编程语言.何为对象?对象是类的实例.在生活中,任何一个事物都是一个对象,如牡丹花.牡丹花的类是花类,同样属于花类的还有荷花.月季花.金银花.菊花 ...

  9. ES中的内置对象--jquery如何优化代码,少用$进行查找,减少查找次数的方法

  10. dapr入门与本地托管模式尝试

    1 简介 Dapr是一个可移植的.事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的.无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架.Dapr支持的语言 ...