public class CacheInterceptorAttribute : AbstractInterceptorAttribute
{
private static readonly ConcurrentDictionary<Type, MethodInfo> TypeofTaskResultMethod = new ConcurrentDictionary<Type, MethodInfo>();
readonly int _expireSecond;
readonly string _cacheKey;
#region 拦截处理
/// <summary>
/// 过期时间,单位:分
/// </summary>
/// <param name="expireMin"></param>
public CacheInterceptorAttribute(string cacheKey = null, int expireMin = -1)
{
_expireSecond = expireMin * 60;
_cacheKey = cacheKey;
}
public async override Task Invoke(AspectContext context, AspectDelegate next)
{
try
{
string key = string.Empty;
//自定义的缓存key不存在,再获取类名+方法名或类名+方法名+参数名的组合式key
if (!string.IsNullOrEmpty(_cacheKey))
{
key = _cacheKey;
}
else
{
key = GetKey(context.ServiceMethod, context.Parameters);
}
var returnType = GetReturnType(context);
var cache = context.ServiceProvider.GetService<ICacheHelper>();
if (!cache.Exists(key))
{
return;
}
var strResult = cache.Get<string>(key);
var result = JsonConvert.DeserializeObject(strResult, returnType);
if (result != null)
{
context.ReturnValue = ResultFactory(result, returnType, context.IsAsync());
}
else
{
result = await RunAndGetReturn(context, next);
if (_expireSecond > 0)
{
cache.Set(key, result, TimeSpan.FromMinutes(_expireSecond));
}
else
{
cache.Set(key, result);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private static string GetKey(MethodInfo method, object[] parameters)
{
return GetKey(method.DeclaringType.Name, method.Name, parameters);
}
private static string GetKey(string className, string methodName, object[] parameters)
{
var paramConcat = parameters.Length == 0 ? string.Empty : ":" + JsonConvert.SerializeObject(parameters);
return $"{className}:{methodName}{paramConcat}";
}
/// <summary>
/// 获取被拦截方法返回值类型
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private Type GetReturnType(AspectContext context)
{
return context.IsAsync()
? context.ServiceMethod.ReturnType.GetGenericArguments().First()
: context.ServiceMethod.ReturnType;
}
/// <summary>
/// 执行被拦截方法
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
private async Task<object> RunAndGetReturn(AspectContext context, AspectDelegate next)
{
await context.Invoke(next);
return context.IsAsync()
? await context.UnwrapAsyncReturnValue()
: context.ReturnValue;
}
/// <summary>
/// 处理拦截器返回结果
/// </summary>
/// <param name="result"></param>
/// <param name="returnType"></param>
/// <param name="isAsync"></param>
/// <returns></returns>
private object ResultFactory(object result, Type returnType, bool isAsync)
{
return !isAsync
? result
: TypeofTaskResultMethod
.GetOrAdd(returnType, t => typeof(Task)
.GetMethods()
.First(p => p.Name == "FromResult" && p.ContainsGenericParameters)
.MakeGenericMethod(returnType))
.Invoke(null, new object[] { result });
}
#endregion
复制代码
多租户
复制代码
public class MultiTenantAttribute : ActionFilterAttribute, IActionFilter
{
///
/// 全局注册过滤器 ,自动为添加 更新方法赋值。也可自行手动打上特性标签
///
///
//private string[] methods = new string[] { “add”, “modify” };
public override void OnActionExecuting(ActionExecutingContext context)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var actionName = actionDescriptor.ActionName.ToLower();
ICacheHelper cache = context.HttpContext.RequestServices.GetRequiredService(typeof(ICacheHelper)) as ICacheHelper;
var siteId = cache.Get(KeyHelper.Cms.CurrentSite)?.Id;
//如果是增加和修改方法 根据站群id
//if (methods.Any(o => actionName.Contains(o)))
//{
foreach (var parameter in actionDescriptor.Parameters)
{
var parameterName = parameter.Name;//获取Action方法中参数的名字
var parameterType = parameter.ParameterType;//获取Action方法中参数的类型
//if (!typeof(int).IsAssignableFrom(parameterType))//如果不是ID类型
//{
// continue;
//}
//自动添加租户id
if (typeof(IGlobalSite).IsAssignableFrom(parameterType))
{
var model = context.ActionArguments[parameterName] as IGlobalSite;
if (siteId != null)
{
model.SiteId = siteId.Value;
}
}
}
//}
}
}
}
复制代码
控制器单表CRUD API
复制代码
///
/// 适用于多租户模块使用
///
/// 实体
/// 详情查询参数实体
/// 删除实体
/// 列表分页查询参数实体
/// 创建实体
/// 更新实体
[Route(“api/[controller]/[action]”)]
[ApiController]
[Authorize]
[MultiTenant]
public abstract class ApiTenantBaseController<TEntity, TDetailQuery, TDeleteInput, TListQuery, TCreateInput, TUpdateInput> : ControllerBase
where TEntity : BaseSiteEntity, new()
where TDetailQuery : DetailSiteQuery
where TDeleteInput : DeletesSiteInput
where TListQuery : ListSiteQuery
where TCreateInput : class
where TUpdateInput : class
{
private readonly IBaseServer _service;
private readonly IMapper _mapper;
public ApiTenantBaseController(IBaseServer<TEntity> service, IMapper mapper)
{
_service = service;
_mapper = mapper;
}
/// <summary>
/// 批量真实删除
/// </summary>
/// <param name="deleteInput"></param>
/// <returns></returns>
[HttpDelete]
public virtual async Task<ApiResult> Deletes([FromBody] TDeleteInput deleteInput)
{
var res = await _service.DeleteAsync(deleteInput.Ids);
if (res <= 0)
{
throw new FriendlyException("删除失败了!");
}
return new ApiResult();
}
/// <summary>
/// 单个真实删除
/// </summary>
/// <param name="deleteInput"></param>
/// <returns></returns>
[HttpDelete]
public virtual async Task<ApiResult> Delete([FromBody] TDeleteInput deleteInput)
{
foreach (var item in deleteInput.Ids)
{
var res = await _service.DeleteAsync(d => d.Id == item && d.SiteId == deleteInput.SiteId);
if (res <= 0)
{
throw new FriendlyException("删除失败了!");
}
}
return new ApiResult();
}
/// <summary>
/// 软删除
/// </summary>
/// <param name="deleteInput"></param>
/// <returns></returns>
[HttpDelete]
public virtual async Task<ApiResult> SoftDelete([FromBody] TDeleteInput deleteInput)
{
foreach (var item in deleteInput.Ids)
{
var res = await _service.UpdateAsync(d => new TEntity() { Status = false }, d => d.Id == item && d.SiteId == deleteInput.SiteId&&d.Status==true);
if (res <= 0)
{
throw new FriendlyException("删除失败了!");
}
}
return new ApiResult();
}
/// <summary>
/// 列表分页
/// </summary>
/// <param name="listQuery">参数实体</param>
/// <returns></returns>
[HttpGet]
public virtual async Task<ApiResult> GetListPages([FromQuery] TListQuery listQuery)
{
var res = await _service.GetPagesAsync(listQuery.Page, listQuery.Limit, d => d.SiteId == listQuery.SiteId&&d.Status==true, d => d.Id, false);
return new ApiResult(data: new { count = res.TotalItems, items = res.Items });
}
/// <summary>
/// 详情
/// </summary>
/// <param name="detailQuery">参数实体</param>
/// <returns></returns>
[HttpGet]
public virtual async Task<ApiResult> Detail([FromQuery] TDetailQuery detailQuery)
{
var res = await _service.GetModelAsync(d => d.Id == detailQuery.Id && d.SiteId == detailQuery.SiteId&&d.Status==true);
return new ApiResult(data: res);
}
/// <summary>
/// 添加
/// </summary>
/// <param name="createInput">添加实体</param>
/// <returns></returns>
[HttpPost]
public virtual async Task<ApiResult> Add([FromBody] TCreateInput createInput)
{
var entity = _mapper.Map<TEntity>(createInput);
var res = await _service.AddAsync(entity);
if (res <= 0)
{
throw new FriendlyException("添加失败了!");
}
return new ApiResult(data: res);
}
/// <summary>
/// 修改-默认忽略更新CreateTime字段
/// </summary>
/// <param name="updateInput">修改实体</param>
/// <returns></returns>
[HttpPut]
public virtual async Task<ApiResult> Modify([FromBody] TUpdateInput updateInput)
{
var entity = _mapper.Map<TEntity>(updateInput);
var res = await _service.UpdateAsync(entity, d => new { d.CreateTime });
if (res <= 0)
{
throw new FriendlyException("修改失败了!");
}
return new ApiResult(data: res);
}
}
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com