提交.Net6版本
This commit is contained in:
92
Yi.Framework.Net5/Yi.Framework.WebCore/Appsettings.cs
Normal file
92
Yi.Framework.Net5/Yi.Framework.WebCore/Appsettings.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yi.Framework.WebCore
|
||||
{
|
||||
/// <summary>
|
||||
/// appsettings.json操作类
|
||||
/// </summary>
|
||||
public class Appsettings
|
||||
{
|
||||
static IConfiguration Configuration { get; set; }
|
||||
static string contentPath { get; set; }
|
||||
|
||||
public Appsettings(string contentPath)
|
||||
{
|
||||
string Path = "appsettings.json";
|
||||
|
||||
//如果你把配置文件 是 根据环境变量来分开了,可以这样写
|
||||
//Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";
|
||||
|
||||
Configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(contentPath)
|
||||
.Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话,可以直接读目录里的json文件,而不是 bin 文件夹下的,所以不用修改复制属性
|
||||
.Build();
|
||||
}
|
||||
|
||||
public Appsettings(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 封装要操作的字符
|
||||
/// </summary>
|
||||
/// <param name="sections">节点配置</param>
|
||||
/// <returns></returns>
|
||||
public static string app(params string[] sections)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (sections.Any())
|
||||
{
|
||||
return Configuration[string.Join(":", sections)];
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static bool appBool(params string[] sections)
|
||||
{
|
||||
|
||||
return Bool(app(sections));
|
||||
|
||||
}
|
||||
|
||||
public static bool Bool(object thisValue)
|
||||
{
|
||||
bool reval = false;
|
||||
if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return reval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归获取配置信息数组
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="sections"></param>
|
||||
/// <returns></returns>
|
||||
public static T app<T>(params string[] sections)
|
||||
{
|
||||
T app = Activator.CreateInstance<T>();
|
||||
// 引用 Microsoft.Extensions.Configuration.Binder 包
|
||||
Configuration.Bind(string.Join(":", sections), app);
|
||||
return app;
|
||||
}
|
||||
|
||||
|
||||
public static IConfiguration appConfiguration(params string[] sections)
|
||||
{
|
||||
return Configuration.GetSection(string.Join(":", sections));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Com.Ctrip.Framework.Apollo;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Com.Ctrip.Framework.Apollo.Enums;
|
||||
using Com.Ctrip.Framework.Apollo.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Yi.Framework.WebCore.BuilderExtend
|
||||
{
|
||||
public static class ApolloExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 接入Apollo
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="jsonPath">apollo配置文件路径 如果写入appsettings.json中 则jsonPath传null即可</param>
|
||||
public static void AddApolloService(this IConfigurationBuilder builder, params string[] NameSpace)
|
||||
{
|
||||
//阿波罗的日志级别调整
|
||||
LogManager.UseConsoleLogging(LogLevel.Warn);
|
||||
var root = builder.Build();
|
||||
|
||||
if (Appsettings.Bool(root["Apollo_Enabled"]))
|
||||
{
|
||||
var apolloBuilder = builder.AddApollo(root.GetSection("apollo")).AddDefault();
|
||||
|
||||
foreach (var item in NameSpace)
|
||||
{
|
||||
apolloBuilder.AddNamespace(item, ConfigFileFormat.Json);
|
||||
}
|
||||
//监听apollo配置
|
||||
Monitor(builder.Build());
|
||||
}
|
||||
|
||||
}
|
||||
#region private
|
||||
/// <summary>
|
||||
/// 监听配置
|
||||
/// </summary>
|
||||
private static void Monitor(IConfigurationRoot root)
|
||||
{
|
||||
//TODO 需要根据改变执行特定的操作 如 mq redis 等其他跟配置相关的中间件
|
||||
//TODO 初步思路:将需要执行特定的操作key和value放入内存字典中,在赋值操作时通过标准事件来执行特定的操作。
|
||||
|
||||
//要重新Build 此时才将Apollo provider加入到ConfigurationBuilder中
|
||||
ChangeToken.OnChange(() => root.GetReloadToken(), () =>
|
||||
{
|
||||
foreach (var apolloProvider in root.Providers.Where(p => p is ApolloConfigurationProvider))
|
||||
{
|
||||
var property = apolloProvider.GetType().BaseType.GetProperty("Data", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var data = property.GetValue(apolloProvider) as IDictionary<string, string>;
|
||||
foreach (var item in data)
|
||||
{
|
||||
Console.WriteLine($"key {item.Key} value {item.Value}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.BuilderExtend
|
||||
{
|
||||
public static class JsonExtension
|
||||
{
|
||||
public static void AddJsonFileService(this IMvcBuilder builder)
|
||||
{
|
||||
builder.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
|
||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm";
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.BuilderExtend
|
||||
{
|
||||
public static class JsonFileExtension
|
||||
{
|
||||
public static void AddJsonFileService(this IConfigurationBuilder builder, params string[] JsonFile)
|
||||
{
|
||||
if (JsonFile==null)
|
||||
{
|
||||
string[] myJsonFile = new string[] { "appsettings.json", "configuration.json" };
|
||||
foreach (var item in myJsonFile)
|
||||
{
|
||||
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in JsonFile)
|
||||
{
|
||||
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Yi.Framework.Net5/Yi.Framework.WebCore/CommonExtend.cs
Normal file
61
Yi.Framework.Net5/Yi.Framework.WebCore/CommonExtend.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Yi.Framework.Model;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Model.Models;
|
||||
|
||||
namespace Yi.Framework.WebCore
|
||||
{
|
||||
public static class CommonExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断是否为异步请求
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAjaxRequest(this HttpRequest request)
|
||||
{
|
||||
string header = request.Headers["X-Requested-With"];
|
||||
return "XMLHttpRequest".Equals(header);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基于HttpContext,当前鉴权方式解析,获取用户信息
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <returns></returns>
|
||||
public static user GetCurrentUserInfo(this HttpContext httpContext, out List<int> menuIds)
|
||||
{
|
||||
IEnumerable<Claim> claimlist = httpContext.AuthenticateAsync().Result.Principal.Claims;
|
||||
|
||||
Int32.TryParse(claimlist.FirstOrDefault(u => u.Type == ClaimTypes.Sid).Value, out int resId);
|
||||
|
||||
|
||||
menuIds = claimlist.Where(u => u.Type == "menuIds").ToList().Select(u => Convert.ToInt32(u.Value)).ToList();
|
||||
|
||||
|
||||
return new user()
|
||||
{
|
||||
id = resId,
|
||||
username = claimlist.FirstOrDefault(u => u.Type == ClaimTypes.Name).Value ?? "匿名"
|
||||
};
|
||||
}
|
||||
public static user GetCurrentUserInfo(this HttpContext httpContext)
|
||||
{
|
||||
IEnumerable<Claim> claimlist = httpContext.AuthenticateAsync().Result.Principal.Claims;
|
||||
|
||||
Int32.TryParse(claimlist.FirstOrDefault(u => u.Type == ClaimTypes.Sid).Value, out int resId);
|
||||
|
||||
return new user()
|
||||
{
|
||||
id = resId,
|
||||
username = claimlist.FirstOrDefault(u => u.Type == ClaimTypes.Name).Value ?? "匿名"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 跨域过滤器
|
||||
/// </summary>
|
||||
public class CORSFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");
|
||||
context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Yi.Framework.Common.Models;
|
||||
using Yi.Framework.Core;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Helper;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 重复提交过滤器
|
||||
/// </summary>
|
||||
public class CustomAction2CommitFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 防重复提交周期 单位秒
|
||||
/// </summary>
|
||||
//public int TimeOut = 1;
|
||||
|
||||
//#region Identity
|
||||
//private readonly ILogger<CustomAction2CommitFilterAttribute> _logger;
|
||||
//private readonly CacheClientDB _cacheClientDB;
|
||||
//private static string KeyPrefix = "2CommitFilter";
|
||||
|
||||
// public CustomAction2CommitFilterAttribute(ILogger<CustomAction2CommitFilterAttribute> logger, CacheClientDB cacheClientDB)
|
||||
// {
|
||||
// this._logger = logger;
|
||||
// this._cacheClientDB = cacheClientDB;
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
|
||||
//if (this.IsAjaxRequest(context.HttpContext.Request))
|
||||
// //{ }
|
||||
// context.Result = new RedirectResult("~/Fourth/Login");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// this._logger.LogDebug($"{currentUser.Name} 访问系统");
|
||||
//}
|
||||
//} public override void OnActionExecuting(ActionExecutingContext context)
|
||||
//{
|
||||
// string url = context.HttpContext.Request.Path.Value;
|
||||
// string argument = JsonConvert.SerializeObject(context.ActionArguments);
|
||||
// string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
|
||||
// string agent = context.HttpContext.Request.Headers["User-Agent"];
|
||||
// string sInfo = $"{url}-{argument}-{ip}-{agent}";
|
||||
// string summary = MD5Helper.MD5EncodingOnly(sInfo);
|
||||
|
||||
// string totalKey = $"{KeyPrefix}-{summary}";
|
||||
|
||||
// string result = this._cacheClientDB.Get<string>(totalKey);
|
||||
// if (string.IsNullOrEmpty(result))
|
||||
// {
|
||||
// this._cacheClientDB.Add(totalKey, "1", TimeSpan.FromSeconds(3));//3秒有效期
|
||||
// this._logger.LogInformation($"CustomAction2CommitFilterAttribute:{sInfo}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //已存在
|
||||
// this._logger.LogWarning($"CustomAction2CommitFilterAttribute重复请求:{sInfo}");
|
||||
// context.Result = new JsonResult(Result.Error("请勿重复提交"));
|
||||
// }
|
||||
|
||||
// //CurrentUser currentUser = context.HttpContext.GetCurrentUserBySession();
|
||||
// //if (currentUser == null)
|
||||
// //{
|
||||
// // //
|
||||
//private bool IsAjaxRequest(HttpRequest request)
|
||||
//{
|
||||
// string header = request.Headers["X-Requested-With"];
|
||||
// return "XMLHttpRequest".Equals(header);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存过滤器
|
||||
/// </summary>
|
||||
public class CustomActionCacheFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("Cache-Control", "public,max-age=6000");
|
||||
Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnActionExecuted{this.Order}");
|
||||
}
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnActionExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnResultExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnResultExecuted{this.Order}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器检查过滤器
|
||||
/// </summary>
|
||||
public class CustomActionCheckFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
#region Identity
|
||||
private readonly ILogger<CustomActionCheckFilterAttribute> _logger;
|
||||
public CustomActionCheckFilterAttribute(ILogger<CustomActionCheckFilterAttribute> logger)
|
||||
{
|
||||
this._logger = logger;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
//CurrentUser currentUser = context.HttpContext.GetCurrentUserBySession();
|
||||
//if (currentUser == null)
|
||||
//{
|
||||
// //if (this.IsAjaxRequest(context.HttpContext.Request))
|
||||
// //{ }
|
||||
// context.Result = new RedirectResult("~/Fourth/Login");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// this._logger.LogDebug($"{currentUser.Name} 访问系统");
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Yi.Framework.Common.Models;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 异常抓取过滤器
|
||||
/// </summary>
|
||||
public class CustomExceptionFilterAttribute : IExceptionFilter
|
||||
{
|
||||
private ILogger<CustomExceptionFilterAttribute> _logger = null;
|
||||
public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger)
|
||||
{
|
||||
this._logger = logger;
|
||||
}
|
||||
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
if (context.ExceptionHandled == false)
|
||||
{
|
||||
context.Result = new JsonResult(
|
||||
Result.Error("操作失败").SetData(context.Exception.Message));
|
||||
string url = context.HttpContext.Request.Path.Value;
|
||||
string actionName = context.ActionDescriptor.DisplayName;
|
||||
|
||||
var logModel = new LogModel()
|
||||
{
|
||||
OriginalClassName = "",
|
||||
OriginalMethodName = actionName,
|
||||
Remark = $"来源于{nameof(CustomExceptionFilterAttribute)}.{nameof(OnException)}"
|
||||
};
|
||||
this._logger.LogError(context.Exception, $"{url}----->actionName={actionName} Message={context.Exception.Message}", JsonConvert.SerializeObject(logModel));
|
||||
}
|
||||
context.ExceptionHandled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 依赖注入工厂过滤器
|
||||
/// </summary>
|
||||
public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
private readonly Type _FilterType = null;
|
||||
|
||||
public CustomIOCFilterFactoryAttribute(Type type)
|
||||
{
|
||||
this._FilterType = type;
|
||||
}
|
||||
public bool IsReusable => true;
|
||||
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
//return (IFilterMetadata)serviceProvider.GetService(typeof(CustomExceptionFilterAttribute));
|
||||
|
||||
return (IFilterMetadata)serviceProvider.GetService(this._FilterType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源过滤器
|
||||
/// </summary>
|
||||
public class CustomResourceFilterAttribute : Attribute, IResourceFilter, IFilterMetadata
|
||||
{
|
||||
private static Dictionary<string, IActionResult> CustomCache = new Dictionary<string, IActionResult>();
|
||||
/// <summary>
|
||||
/// 发生在其他动作之前
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuting");
|
||||
//if 有缓存,直接返回缓存
|
||||
string key = context.HttpContext.Request.Path;
|
||||
if (CustomCache.ContainsKey(key))
|
||||
{
|
||||
context.Result = CustomCache[key];//断路器--到Result生成了,但是Result还需要转换成Html
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发生在其他动作之后
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuted");
|
||||
//这个应该缓存起来
|
||||
string key = context.HttpContext.Request.Path;
|
||||
if (!CustomCache.ContainsKey(key))
|
||||
{
|
||||
CustomCache.Add(key, context.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Yi.Framework.Common.Models;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.FilterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志处理过滤器
|
||||
/// </summary>
|
||||
public class LogActionFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
private ILogger<LogActionFilterAttribute> _logger = null;
|
||||
public LogActionFilterAttribute(ILogger<LogActionFilterAttribute> logger)
|
||||
{
|
||||
this._logger = logger;
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
string url = context.HttpContext.Request.Path.Value;
|
||||
string argument = JsonConvert.SerializeObject(context.ActionArguments);
|
||||
|
||||
string controllerName = context.Controller.GetType().FullName;
|
||||
string actionName = context.ActionDescriptor.DisplayName;
|
||||
|
||||
LogModel logModel = new LogModel()
|
||||
{
|
||||
OriginalClassName = controllerName,
|
||||
OriginalMethodName = actionName,
|
||||
Remark = $"来源于{nameof(LogActionFilterAttribute)}.{nameof(OnActionExecuting)}"
|
||||
};
|
||||
|
||||
//this._logger.LogInformation($"url={url}---argument={argument}",new object[] { JsonConvert.SerializeObject(logModel) } );
|
||||
this._logger.LogInformation($"url={url}---argument={argument}");
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomActionFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(LogActionFilterAttribute)} OnActionExecuted{this.Order}");
|
||||
}
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(LogActionFilterAttribute)} OnActionExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(LogActionFilterAttribute)} OnResultExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(LogActionFilterAttribute)} OnResultExecuted{this.Order}");
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomControllerFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuted {this.Order}");
|
||||
}
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuting{this.Order}");
|
||||
}
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuted{this.Order}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
258
Yi.Framework.Net5/Yi.Framework.WebCore/Init/DataSeed.cs
Normal file
258
Yi.Framework.Net5/Yi.Framework.WebCore/Init/DataSeed.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
using Yi.Framework.Model.Models;
|
||||
|
||||
namespace Yi.Framework.WebCore.Init
|
||||
{
|
||||
public class DataSeed
|
||||
{
|
||||
public async static Task SeedAsync(IDbContextFactory _DbFactory)
|
||||
{
|
||||
var _Db = _DbFactory.ConnWriteOrRead(Common.Enum.WriteAndReadEnum.Write);
|
||||
if (!_Db.Set<user>().Any())
|
||||
{
|
||||
await _Db.Set<user>().AddAsync(new user
|
||||
{
|
||||
username = "admin",
|
||||
password = "123",
|
||||
roles = new List<role>()
|
||||
{
|
||||
new role(){ role_name="普通用户"},
|
||||
|
||||
new role()
|
||||
{
|
||||
role_name="管理员",
|
||||
menus = new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="根",is_show=1,is_top=1, children=new List<menu>(){
|
||||
new menu()
|
||||
{
|
||||
menu_name="首页",is_show=1,router="/"
|
||||
},
|
||||
|
||||
new menu()
|
||||
{
|
||||
menu_name="用户角色管理",is_show=1, children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="用户管理",router="/AdmUser/", is_show=1,children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="get",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="get",url="/user/getuser"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="update",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="update",url="/user/updateuser"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="del",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="del",url="/user/dellistUser"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="add",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="add",url="/user/adduser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="角色管理",router="/admrole/", is_show=1,children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="get",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="get",url="/role/getrole"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="update",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="update",url="/role/updaterole"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="del",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="del",url="/role/dellistrole"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="add",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="add",url="/role/addrole"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="角色接口管理",is_show=1, children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="菜单管理",router="/AdmMenu/", is_show=1,children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="get",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="get",url="/Menu/getMenu"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="update",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="update",url="/Menu/updateMenu"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="del",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="del",url="/Menu/dellistMenu"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="add",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="add",url="/Menu/addMenu"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="接口管理",router="/admMould/", is_show=1,children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="get",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="get",url="/Mould/getMould"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="update",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="update",url="/Mould/updateMould"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="del",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="del",url="/Mould/dellistMould"
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="add",is_show=0,
|
||||
mould=new mould()
|
||||
{
|
||||
mould_name="add",url="/Mould/addMould"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="角色菜单分配管理",router="/admRoleMenu/", is_show=1, children=null
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
new menu()
|
||||
{
|
||||
menu_name="路由管理",is_show=1,children=new List<menu>()
|
||||
{
|
||||
new menu()
|
||||
{
|
||||
menu_name="用户信息",router="/userinfo/", is_show=1,children=null
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
await _Db.SaveChangesAsync();
|
||||
|
||||
Console.WriteLine(nameof(DbContext) + ":数据库初始成功!");
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Yi.Framework.Net5/Yi.Framework.WebCore/Init/RedisInit.cs
Normal file
31
Yi.Framework.Net5/Yi.Framework.WebCore/Init/RedisInit.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Const;
|
||||
using Yi.Framework.Core;
|
||||
using Yi.Framework.DTOModel;
|
||||
|
||||
namespace Yi.Framework.WebCore.Init
|
||||
{
|
||||
public class RedisInit
|
||||
{
|
||||
public static void Seed(CacheClientDB _cacheClientDB)
|
||||
{
|
||||
var setDto = Common.Helper.JsonHelper.ObjToStr(new SettingDto()
|
||||
{
|
||||
ImageList =new List<string> { "默认图片", "默认图片" },
|
||||
InitRole = "普通用户",
|
||||
Title = "YiFramework",
|
||||
InitIcon = "默认头像"
|
||||
});
|
||||
if (_cacheClientDB.Get<SettingDto>(RedisConst.key)==null)
|
||||
{
|
||||
_cacheClientDB.Add(RedisConst.key,setDto) ;
|
||||
}
|
||||
|
||||
Console.WriteLine(nameof(RedisInit) + ":Redis初始成功!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using DotNetCore.CAP.Dashboard.NodeDiscovery;
|
||||
using DotNetCore.CAP.Messages;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
public static class CAPExtend
|
||||
{
|
||||
public static IServiceCollection AddCAPService<T>(this IServiceCollection services)
|
||||
{
|
||||
if (Appsettings.appBool("CAP_Enabled"))
|
||||
{
|
||||
services.AddCap(x =>
|
||||
{
|
||||
x.UseMySql(Appsettings.app("DbConn", "WriteUrl"));
|
||||
|
||||
x.UseRabbitMQ(optios => {
|
||||
optios.HostName = Appsettings.app("RabbitConn", "HostName");
|
||||
optios.Port =Convert.ToInt32(Appsettings.app("RabbitConn", "Port"));
|
||||
optios.UserName = Appsettings.app("RabbitConn", "UserName");
|
||||
optios.Password = Appsettings.app("RabbitConn", "Password");
|
||||
|
||||
});
|
||||
x.FailedRetryCount = 30;
|
||||
x.FailedRetryInterval = 60;//second
|
||||
x.FailedThresholdCallback = failed =>
|
||||
{
|
||||
var logger = failed.ServiceProvider.GetService<ILogger<T>>();
|
||||
logger.LogError($@"MessageType {failed.MessageType} 失败了, 重试了 {x.FailedRetryCount} 次,
|
||||
消息名称: {failed.Message.GetName()}");//do anything
|
||||
};
|
||||
if (Appsettings.appBool("CAPDashboard_Enabled"))
|
||||
{
|
||||
x.UseDashboard();
|
||||
var discoveryOptions = Appsettings.app<DiscoveryOptions>();
|
||||
x.UseDiscovery(d =>
|
||||
{
|
||||
d.DiscoveryServerHostName = discoveryOptions.DiscoveryServerHostName;
|
||||
d.DiscoveryServerPort = discoveryOptions.DiscoveryServerPort;
|
||||
d.CurrentNodeHostName = discoveryOptions.CurrentNodeHostName;
|
||||
d.CurrentNodePort = discoveryOptions.CurrentNodePort;
|
||||
d.NodeId = discoveryOptions.NodeId;
|
||||
d.NodeName = discoveryOptions.NodeName;
|
||||
d.MatchPath = discoveryOptions.MatchPath;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Consul;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// HTTP模式
|
||||
/// </summary>
|
||||
public static class ConsulRegiterExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 基于提供信息完成注册
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="healthService"></param>
|
||||
/// <returns></returns>
|
||||
public static void UseConsulService(this IApplicationBuilder app)
|
||||
{
|
||||
|
||||
if (Appsettings.appBool("Consul_Enabled"))
|
||||
{
|
||||
var consulRegisterOption = Appsettings.app<ConsulRegisterOption>("ConsulRegisterOption");
|
||||
|
||||
var consulClientOption = Appsettings.app<ConsulClientOption>("ConsulClientOption");
|
||||
using (ConsulClient client = new ConsulClient(c =>
|
||||
{
|
||||
c.Address = new Uri($"http://{consulClientOption.IP}:{consulClientOption.Port}/");
|
||||
c.Datacenter = consulClientOption.Datacenter;
|
||||
}))
|
||||
{
|
||||
client.Agent.ServiceRegister(new AgentServiceRegistration()
|
||||
{
|
||||
ID = $"{consulRegisterOption.IP}-{consulRegisterOption.Port}-{Guid.NewGuid()}",//唯一Id
|
||||
Name = consulRegisterOption.GroupName,//组名称-Group
|
||||
Address = consulRegisterOption.IP,
|
||||
Port = consulRegisterOption.Port,
|
||||
Tags = new string[] { consulRegisterOption.Tag },
|
||||
Check = new AgentServiceCheck()
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(consulRegisterOption.Interval),
|
||||
HTTP = $"http://{consulRegisterOption.IP}:{consulRegisterOption.Port}{consulRegisterOption.HealthCheckUrl}",
|
||||
Timeout = TimeSpan.FromSeconds(consulRegisterOption.Timeout),
|
||||
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(consulRegisterOption.DeregisterCriticalServiceAfter)
|
||||
}
|
||||
}).Wait();
|
||||
Console.WriteLine($"{JsonConvert.SerializeObject(consulRegisterOption)} 完成注册");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用跨域扩展
|
||||
/// </summary>
|
||||
public static class CorsExtension
|
||||
{
|
||||
public static IServiceCollection AddCorsService(this IServiceCollection services)
|
||||
{
|
||||
|
||||
if (Appsettings.appBool("Cors_Enabled"))
|
||||
{
|
||||
services.AddCors(options => options.AddPolicy("CorsPolicy",//解决跨域问题
|
||||
builder =>
|
||||
{
|
||||
builder.AllowAnyMethod()
|
||||
.SetIsOriginAllowed(_ => true)
|
||||
.AllowAnyHeader()
|
||||
.AllowCredentials();
|
||||
}));
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
public static void UseCorsService(this IApplicationBuilder app)
|
||||
{
|
||||
if (Appsettings.appBool("Cors_Enabled"))
|
||||
{
|
||||
app.UseCors("CorsPolicy");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
using Yi.Framework.Model;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
public static class DbExtend
|
||||
{
|
||||
public static IServiceCollection AddDbService(this IServiceCollection services)
|
||||
{
|
||||
DbContextFactory.MutiDB_Enabled = Appsettings.appBool("MutiDB_Enabled");
|
||||
DataContext.DbSelect = Appsettings.app("DbSelect");
|
||||
DataContext._connStr = Appsettings.app("DbConn", "WriteUrl");
|
||||
services.Configure<DbConnOptions>(Appsettings.appConfiguration("DbConn"));
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
using Yi.Framework.WebCore.Init;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
public static class DbSeedInitExtend
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(DbSeedInitExtend));
|
||||
public static void UseDbSeedInitService(this IApplicationBuilder app, IDbContextFactory _DbFactory)
|
||||
{
|
||||
|
||||
if (Appsettings.appBool("DbSeed_Enabled"))
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
||||
try
|
||||
{
|
||||
DataSeed.SeedAsync(_DbFactory).Wait();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error($"Error occured seeding the Database.\n{e.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
using Yi.Framework.Core;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis扩展
|
||||
/// </summary>
|
||||
public static class ElasticSeachExtend
|
||||
{
|
||||
public static IServiceCollection AddElasticSeachService(this IServiceCollection services)
|
||||
{
|
||||
if (Appsettings.appBool("ElasticSeach_Enabled"))
|
||||
{
|
||||
services.Configure<ElasticSearchOptions>(Appsettings.appConfiguration("ElasticSeachConn"));
|
||||
services.AddTransient<ElasticSearchInvoker>();
|
||||
}
|
||||
return services;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Models;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 异常抓取反馈扩展
|
||||
/// </summary>
|
||||
public class ErrorHandExtension
|
||||
{
|
||||
private readonly RequestDelegate next;
|
||||
|
||||
public ErrorHandExtension(RequestDelegate next)
|
||||
{
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var statusCode = context.Response.StatusCode;
|
||||
if (ex is ArgumentException)
|
||||
{
|
||||
statusCode = 200;
|
||||
}
|
||||
await HandleExceptionAsync(context, statusCode, ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
var statusCode = context.Response.StatusCode;
|
||||
var msg = "";
|
||||
|
||||
switch (statusCode)
|
||||
{
|
||||
case 401: msg = "未授权";break;
|
||||
case 403: msg = "未授权"; break;
|
||||
case 404: msg = "未找到服务"; break;
|
||||
case 502: msg = "请求错误"; break;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(msg))
|
||||
{
|
||||
await HandleExceptionAsync(context, statusCode, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
//异常错误信息捕获,将错误信息用Json方式返回
|
||||
private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg)
|
||||
{
|
||||
Result resp;
|
||||
if (statusCode == 401)
|
||||
{
|
||||
resp = Result.UnAuthorize(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp = Result.Error(msg);
|
||||
}
|
||||
var result = JsonConvert.SerializeObject(resp);
|
||||
context.Response.ContentType = "application/json;charset=utf-8";
|
||||
return context.Response.WriteAsync(result);
|
||||
}
|
||||
}
|
||||
//扩展方法
|
||||
public static class ErrorHandlingExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseErrorHandlingService(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<ErrorHandExtension>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 健康检测扩展
|
||||
/// </summary>
|
||||
public static class HealthCheckExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置心跳响应
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="checkPath">默认是/Health</param>
|
||||
/// <returns></returns>
|
||||
public static void UseHealthCheckMiddleware(this IApplicationBuilder app, string checkPath = "/Health")
|
||||
{
|
||||
if (Appsettings.appBool("HealthCheck_Enabled"))
|
||||
{
|
||||
app.Map(checkPath, applicationBuilder => applicationBuilder.Run(async context =>
|
||||
{
|
||||
Console.WriteLine($"This is Health Check");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
await context.Response.WriteAsync("OK");
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Model;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用跨域扩展
|
||||
/// </summary>
|
||||
public static class IocExtension
|
||||
{
|
||||
public static IServiceCollection AddIocService(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
#region
|
||||
//配置文件使用配置
|
||||
#endregion
|
||||
services.AddSingleton(new Appsettings(configuration));
|
||||
#region
|
||||
//数据库配置
|
||||
#endregion
|
||||
services.AddTransient<DbContext, DataContext>();
|
||||
return services;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Yi.Framework.Common.Const;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用跨域扩展
|
||||
/// </summary>
|
||||
public static class JwtExtension
|
||||
{
|
||||
public static IServiceCollection AddJwtService(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,//是否验证Issuer
|
||||
ValidateAudience = true,//是否验证Audience
|
||||
ValidateLifetime = true,//是否验证失效时间
|
||||
ClockSkew = TimeSpan.FromDays(1),
|
||||
|
||||
ValidateIssuerSigningKey = true,//是否验证SecurityKey
|
||||
ValidAudience = JwtConst.Domain,//Audience
|
||||
ValidIssuer = JwtConst.Domain,//Issuer,这两项和前面签发jwt的设置一致
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//拿到SecurityKey
|
||||
};
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 预检请求扩展
|
||||
/// </summary>
|
||||
public class PreOptionRequestExtension
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public PreOptionRequestExtension(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (context.Request.Method.ToUpper() == "OPTIONS")
|
||||
{
|
||||
//context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:8070");
|
||||
//context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
|
||||
//context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
|
||||
context.Response.StatusCode = 200;
|
||||
return;
|
||||
}
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扩展中间件
|
||||
/// </summary>
|
||||
public static class PreOptionsRequestMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UsePreOptionsRequest(this IApplicationBuilder app)
|
||||
{
|
||||
return app.UseMiddleware<PreOptionRequestExtension>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
using Quartz.Spi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Core;
|
||||
using Yi.Framework.Core.Quartz;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动定时器服务,后台服务
|
||||
/// </summary>
|
||||
public static class QuartzExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用定时器
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddQuartzService(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<QuartzInvoker>();
|
||||
services.AddSingleton<IJobFactory, MyQuartzFactory>();
|
||||
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
using Yi.Framework.Core;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis扩展
|
||||
/// </summary>
|
||||
public static class RabbitMQExtension
|
||||
{
|
||||
public static IServiceCollection AddRabbitMQService(this IServiceCollection services)
|
||||
{
|
||||
if (Appsettings.appBool("RabbitMQ_Enabled"))
|
||||
{
|
||||
services.Configure<RabbitMQOptions>(Appsettings.appConfiguration("RabbitConn"));
|
||||
services.AddTransient<RabbitMQInvoker>();
|
||||
}
|
||||
return services;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
using Yi.Framework.Core;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis扩展
|
||||
/// </summary>
|
||||
public static class RedisExtension
|
||||
{
|
||||
public static IServiceCollection AddRedisService(this IServiceCollection services)
|
||||
{
|
||||
if (Appsettings.appBool("Redis_Enabled"))
|
||||
{
|
||||
services.Configure<RedisConnOptions>(Appsettings.appConfiguration("RedisConnOptions"));
|
||||
services.AddTransient<CacheClientDB>();
|
||||
}
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Core;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
using Yi.Framework.WebCore.Init;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
public static class RedisInitExtend
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(RedisInitExtend));
|
||||
public static void UseRedisSeedInitService(this IApplicationBuilder app, CacheClientDB _cacheClientDB)
|
||||
{
|
||||
|
||||
if (Appsettings.appBool("RedisSeed_Enabled"))
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
||||
try
|
||||
{
|
||||
RedisInit.Seed(_cacheClientDB);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error($"Error occured seeding the RedisInit.\n{e.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Common.IOCOptions;
|
||||
using Yi.Framework.Core;
|
||||
using Yi.Framework.Core.SMS;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis扩展
|
||||
/// </summary>
|
||||
public static class SMSExtension
|
||||
{
|
||||
public static IServiceCollection AddSMSService(this IServiceCollection services)
|
||||
{
|
||||
if (Appsettings.appBool("SMS_Enabled"))
|
||||
{
|
||||
|
||||
services.Configure<SMSOptions>(Appsettings.appConfiguration("SMS"));
|
||||
services.AddTransient<AliyunSMSInvoker>();
|
||||
}
|
||||
return services;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态化页面处理扩展
|
||||
/// </summary>
|
||||
public class StaticPageExtension
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private string _directoryPath = @"D:/cc-yi/";
|
||||
private bool _supportDelete = false;
|
||||
private bool _supportWarmup = false;
|
||||
|
||||
public StaticPageExtension(RequestDelegate next, string directoryPath, bool supportDelete, bool supportWarmup)
|
||||
{
|
||||
this._next = next;
|
||||
this._directoryPath = directoryPath;
|
||||
this._supportDelete = supportDelete;
|
||||
this._supportWarmup = supportWarmup;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
if (this._supportDelete && "Delete".Equals(context.Request.Query["ActionHeader"]))
|
||||
{
|
||||
this.DeleteHmtl(context.Request.Path.Value);
|
||||
context.Response.StatusCode = 200;
|
||||
}
|
||||
else if (this._supportWarmup && "ClearAll".Equals(context.Request.Query["ActionHeader"]))
|
||||
{
|
||||
this.ClearDirectory(10);//考虑数据量
|
||||
context.Response.StatusCode = 200;
|
||||
}
|
||||
else if (!context.Request.IsAjaxRequest())
|
||||
{
|
||||
Console.WriteLine($"This is StaticPageMiddleware InvokeAsync {context.Request.Path.Value}");
|
||||
#region context.Response.Body
|
||||
var originalStream = context.Response.Body;
|
||||
using (var copyStream = new MemoryStream())
|
||||
{
|
||||
context.Response.Body = copyStream;
|
||||
await _next(context);
|
||||
|
||||
copyStream.Position = 0;
|
||||
var reader = new StreamReader(copyStream);
|
||||
var content = await reader.ReadToEndAsync();
|
||||
string url = context.Request.Path.Value;
|
||||
|
||||
this.SaveHmtl(url, content);
|
||||
|
||||
copyStream.Position = 0;
|
||||
await copyStream.CopyToAsync(originalStream);
|
||||
context.Response.Body = originalStream;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveHmtl(string url, string html)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Console.WriteLine($"Response: {html}");
|
||||
if (string.IsNullOrWhiteSpace(html))
|
||||
return;
|
||||
if (!url.EndsWith(".html"))
|
||||
return;
|
||||
|
||||
if (Directory.Exists(_directoryPath) == false)
|
||||
Directory.CreateDirectory(_directoryPath);
|
||||
|
||||
var totalPath = Path.Combine(_directoryPath, url.Split("/").Last());
|
||||
File.WriteAllText(totalPath, html);//直接覆盖
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除某个页面
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="index"></param>
|
||||
private void DeleteHmtl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!url.EndsWith(".html"))
|
||||
return;
|
||||
var totalPath = Path.Combine(_directoryPath, url.Split("/").Last());
|
||||
File.Delete(totalPath);//直接删除
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Delete {url} 异常,{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理文件,支持重试
|
||||
/// </summary>
|
||||
/// <param name="index">最多重试次数</param>
|
||||
private void ClearDirectory(int index)
|
||||
{
|
||||
if (index > 0)//简陋版---重试index次
|
||||
{
|
||||
try
|
||||
{
|
||||
var files = Directory.GetFiles(_directoryPath);
|
||||
foreach (var file in files)
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ClearDirectory failed {ex.Message}");
|
||||
ClearDirectory(index--);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扩展中间件
|
||||
/// </summary>
|
||||
public static class StaticPageMiddlewareExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="directoryPath">文件写入地址,文件夹目录</param>
|
||||
/// <param name="supportDelete">是否支持删除</param>
|
||||
/// <param name="supportClear">是否支持全量删除</param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseStaticPageMiddleware(this IApplicationBuilder app, string directoryPath, bool supportDelete, bool supportClear)
|
||||
{
|
||||
return app.UseMiddleware<StaticPageExtension>(directoryPath, supportDelete, supportClear);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using IGeekFan.AspNetCore.Knife4jUI;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Yi.Framework.Common.Models;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// Swagger扩展
|
||||
/// </summary>
|
||||
public static class SwaggerExtension
|
||||
{
|
||||
public static IServiceCollection AddSwaggerService<Program>(this IServiceCollection services, string title = "Yi意框架-API接口")
|
||||
{
|
||||
var apiInfo = new OpenApiInfo
|
||||
{
|
||||
Title = title,
|
||||
Version = "v1",
|
||||
Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://ccnetcore.com") }
|
||||
};
|
||||
#region 注册Swagger服务
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", apiInfo);
|
||||
|
||||
//添加注释服务
|
||||
//为 Swagger JSON and UI设置xml文档注释路径
|
||||
//获取应用程序所在目录(绝对路径,不受工作目录影响,建议采用此方法获取路径使用windwos&Linux)
|
||||
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
||||
var apiXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//控制器层注释
|
||||
//var entityXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//实体注释
|
||||
//c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释
|
||||
c.IncludeXmlComments(apiXmlPath,true);
|
||||
|
||||
//添加控制器注释
|
||||
//c.DocumentFilter<SwaggerDocTag>();
|
||||
|
||||
//添加header验证信息
|
||||
//c.OperationFilter<SwaggerHeader>();
|
||||
//var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
|
||||
|
||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
|
||||
{
|
||||
Description = "文本框里输入从服务器获取的Token。格式为:Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"
|
||||
Name = "Authorization",////jwt默认的参数名称
|
||||
In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中)
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
});
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{ new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference()
|
||||
{
|
||||
Id = "Bearer",
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
}, Array.Empty<string>() }
|
||||
});
|
||||
|
||||
c.AddServer(new OpenApiServer()
|
||||
{
|
||||
Url = "https://ccnetcore.com",
|
||||
Description = "Yi-Framework"
|
||||
});
|
||||
c.CustomOperationIds(apiDesc =>
|
||||
{
|
||||
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||
return controllerAction.ActionName;
|
||||
});
|
||||
});
|
||||
#endregion
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static void UseSwaggerService(this IApplicationBuilder app, params SwaggerModel[] swaggerModels)
|
||||
{
|
||||
//在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务:
|
||||
// Enable middleware to serve generated Swagger as a JSON endpoint.
|
||||
app.UseSwagger();
|
||||
|
||||
|
||||
app.UseKnife4UI(c =>
|
||||
{
|
||||
c.RoutePrefix = "swagger"; // serve the UI at root
|
||||
if (swaggerModels.Length == 0)
|
||||
{
|
||||
c.SwaggerEndpoint("/v1/swagger.json", "Yi.Framework");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var k in swaggerModels)
|
||||
{
|
||||
c.SwaggerEndpoint(k.url, k.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//app.UseSwaggerUI(c =>
|
||||
//{
|
||||
// if (swaggerModels.Length == 0)
|
||||
// {
|
||||
// c.SwaggerEndpoint("/swagger/v1/swagger.json", "Yi.Framework");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// foreach (var k in swaggerModels)
|
||||
// {
|
||||
// c.SwaggerEndpoint(k.url, k.name);
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Castle.DynamicProxy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.WebCore.Utility
|
||||
{
|
||||
public class CustomAutofacAop : IInterceptor
|
||||
{
|
||||
public void Intercept(IInvocation invocation)
|
||||
{
|
||||
Console.WriteLine($"invocation.Methond={invocation.Method}");
|
||||
Console.WriteLine($"invocation.Arguments={string.Join(",", invocation.Arguments)}");
|
||||
|
||||
invocation.Proceed(); //继续执行
|
||||
|
||||
Console.WriteLine($"方法{invocation.Method}执行完成了");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using Autofac;
|
||||
using Autofac.Extras.DynamicProxy;
|
||||
using Castle.DynamicProxy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Job;
|
||||
using Yi.Framework.Model.ModelFactory;
|
||||
using Yi.Framework.WebCore.Utility;
|
||||
using Module = Autofac.Module;
|
||||
|
||||
namespace Yi.Framework.WebCore.Utility
|
||||
{
|
||||
public class CustomAutofacModule : Module
|
||||
{
|
||||
private Assembly GetDll(string ass)
|
||||
{
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
var servicesDllFile = Path.Combine(basePath, ass);
|
||||
if (!(File.Exists(servicesDllFile)))
|
||||
{
|
||||
var msg = "service.dll 丢失,请编译后重新生成。";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
return Assembly.LoadFrom(servicesDllFile); ;
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder containerBuilder)
|
||||
{
|
||||
|
||||
containerBuilder.RegisterType<DbContextFactory>().As<IDbContextFactory>().InstancePerDependency().EnableInterfaceInterceptors();
|
||||
|
||||
containerBuilder.RegisterType< HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
|
||||
|
||||
|
||||
|
||||
///反射注入服务层及接口层
|
||||
var assemblysServices = GetDll( "Yi.Framework.Service.dll");
|
||||
containerBuilder.RegisterAssemblyTypes(assemblysServices)
|
||||
.AsImplementedInterfaces()
|
||||
.InstancePerDependency()
|
||||
.EnableInterfaceInterceptors();
|
||||
|
||||
///反射注册任务调度层
|
||||
var assemblysJob = GetDll("Yi.Framework.Job.dll");
|
||||
containerBuilder.RegisterAssemblyTypes(assemblysJob)
|
||||
.InstancePerDependency();
|
||||
|
||||
|
||||
|
||||
containerBuilder.Register(c => new CustomAutofacAop());//AOP注册
|
||||
|
||||
|
||||
//containerBuilder.RegisterType<A>().As<IA>().EnableInterfaceInterceptors();开启Aop
|
||||
|
||||
//将数据库对象注入
|
||||
//containerBuilder.RegisterType<DataContext>().As<DbContext>().InstancePerLifetimeScope().EnableInterfaceInterceptors();
|
||||
|
||||
//containerBuilder.RegisterGeneric(typeof(BaseService<>)).As(typeof(IBaseService<>)).InstancePerDependency().EnableInterfaceInterceptors();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface IAutofacTest
|
||||
{
|
||||
void Show(int id, string name);
|
||||
}
|
||||
|
||||
[Intercept(typeof(CustomAutofacAop))]
|
||||
public class AutofacTest : IAutofacTest
|
||||
{
|
||||
public void Show(int id, string name)
|
||||
{
|
||||
Console.WriteLine($"This is {id} _ {name}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
[assembly: HostingStartup(typeof(Yi.Framework.WebCore.Utility.CustomHostingStartup))]
|
||||
namespace Yi.Framework.WebCore.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 必须实现IHostingStartup接口
|
||||
/// 必须标记HostingStartup特性
|
||||
///
|
||||
/// 就像木马一样
|
||||
/// </summary>
|
||||
public class CustomHostingStartup : IHostingStartup
|
||||
{
|
||||
public void Configure(IWebHostBuilder builder)
|
||||
{
|
||||
Console.WriteLine("This is CustomHostingStartup Invoke");
|
||||
|
||||
//有IWebHostBuilder,一切都可以做。。
|
||||
#region MyRegion
|
||||
//builder.ConfigureAppConfiguration(configurationBuilder =>
|
||||
//{
|
||||
// configurationBuilder.AddXmlFile("appsettings1.xml", optional: false, reloadOnChange: true);
|
||||
//});//添加配置
|
||||
|
||||
//builder.ConfigureServices(services =>
|
||||
//{
|
||||
// services.AddTransient<ITestServiceA, TestServiceA>();
|
||||
//});//IOC注册
|
||||
|
||||
//builder.Configure(app =>
|
||||
//{
|
||||
// app.Use(next =>
|
||||
// {
|
||||
// Console.WriteLine("This is CustomHostingStartup-Middleware Init");
|
||||
// return new RequestDelegate(
|
||||
// async context =>
|
||||
// {
|
||||
// Console.WriteLine("This is CustomHostingStartup-Middleware start");
|
||||
// await next.Invoke(context);
|
||||
// Console.WriteLine("This is CustomHostingStartup-Middleware end");
|
||||
// });
|
||||
// });
|
||||
//});//甚至来个中间件
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.3.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
|
||||
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="6.0.0" />
|
||||
<PackageReference Include="Com.Ctrip.Framework.Apollo.Configuration" Version="2.4.1.1" />
|
||||
<PackageReference Include="DotNetCore.CAP" Version="5.2.0" />
|
||||
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="5.2.0" />
|
||||
<PackageReference Include="DotNetCore.CAP.MySql" Version="5.2.0" />
|
||||
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="5.2.0" />
|
||||
<PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.4" />
|
||||
<PackageReference Include="Quartz.AspNetCore" Version="3.3.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.DTOModel\Yi.Framework.DTOModel.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.Model\Yi.Framework.Model.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user