public object GetFrameFilesByTableNames([FromBody] string[] tableNames, [FromQuery] string ConnID = null) { //ConnID = ConnID == null ? MainDb.CurrentDbConnId.ToLower() : ConnID; //ConnID = ConnID ?? MainDb.CurrentDbConnId.ToLower(); ConnID ??= MainDb.CurrentDbConnId.ToLower(); var isMuti = Appsettings.App(new string[] { "MutiDBEnabled" }).ToBoolReq(); var data = new MessageModel <string>() { Success = true, Message = "" }; if (Env.IsDevelopment()) { //data.Response += $"库{ConnID}-IRepositorys层生成:{FrameSeed.CreateIRepositorys(_sqlSugarClient, ConnID, isMuti, tableNames)} || "; data.Response += $"库{ConnID}-IServices层生成:{FrameSeed.CreateIServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || "; //data.Response += $"库{ConnID}-Repository层生成:{FrameSeed.CreateRepository(_sqlSugarClient, ConnID, isMuti, tableNames)} || "; data.Response += $"库{ConnID}-Services层生成:{FrameSeed.CreateServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || "; } else { data.Success = false; data.Message = "当前不处于开发模式,代码生成不可用!"; } return(data); }
public object GetFrameFiles() { var data = new MessageModel <string>() { Success = true, Message = "" }; data.Response += @"file path is:D:\my-file\}"; var isMuti = Appsettings.App(new string[] { "MutiDBEnabled" }).ToBoolReq(); if (Env.IsDevelopment()) { data.Response += $"Controller层生成:{FrameSeed.CreateControllers(_sqlSugarClient)} || "; BaseDBConfig.MutiConnectionString.Item1.ToList().ForEach(m => { _sqlSugarClient.ChangeDatabase(m.ConnId.ToLower()); data.Response += $"库{m.ConnId}-Model层生成:{FrameSeed.CreateModels(_sqlSugarClient, m.ConnId, isMuti)} || "; //data.Response += $"库{m.ConnId}-IRepositorys层生成:{FrameSeed.CreateIRepositorys(_sqlSugarClient, m.ConnId, isMuti)} || "; data.Response += $"库{m.ConnId}-IServices层生成:{FrameSeed.CreateIServices(_sqlSugarClient, m.ConnId, isMuti)} || "; //data.Response += $"库{m.ConnId}-Repository层生成:{FrameSeed.CreateRepository(_sqlSugarClient, m.ConnId, isMuti)} || "; data.Response += $"库{m.ConnId}-Services层生成:{FrameSeed.CreateServices(_sqlSugarClient, m.ConnId, isMuti)} || "; }); // 切回主库 _sqlSugarClient.ChangeDatabase(MainDb.CurrentDbConnId.ToLower()); } else { data.Success = false; data.Message = "当前不处于开发模式,代码生成不可用!"; } return(data); }
public static string IssueJwt(TokenModelJwt tokenModelJwt) { var iss = Appsettings.App("Audience", "Issuer"); var aud = Appsettings.App("Audience", "Audience"); var secret = Appsettings.App("Audience", "Secret"); var claims = new List <Claim> { /* * 特别重要: * 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! * 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 */ new Claim(JwtRegisteredClaimNames.Jti, tokenModelJwt.Uid.ToString()), new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), // 过期时间 new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeMilliseconds()}"), new Claim(JwtRegisteredClaimNames.Iss, iss), new Claim(JwtRegisteredClaimNames.Aud, aud), }; // 一个用户多个身份 claims.AddRange(tokenModelJwt.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken(claims: claims, signingCredentials: creds); var jwtHandler = new JwtSecurityTokenHandler(); var encodedJwt = jwtHandler.WriteToken(jwt); return(encodedJwt); }
public static void AddRedisInitMqSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "Startup", "RedisMq", "Enabled" }).ToBoolReq()) { // services.AddInitQ(m => { //时间间隔 m.SuspendTime = 2000; //redis服务器地址 m.ConnectionString = Appsettings.App(new string[] { "Redis", "ConnectionString" }); //对应的订阅者类,需要new一个实例对象,当然你也可以传参,比如日志对象 m.ListSubscribe = new List <Type>() { //typeof(RedisSubscribe), //typeof(RedisSubscribe2) }; //显示日志 m.ShowLog = false; }); } }
/// <summary> /// 颁发Jwt字符串 /// </summary> /// <param name="tokenModel">Jwt令牌</param> /// <returns>Jwt字符串</returns> public static string IssueJwt(JwtTokenModel tokenModel) { string issue = Appsettings.App(new string[] { "Audience", "Issuer" }); string audience = Appsettings.App(new string[] { "Audience", "Audience" }); string secret = AppSecretConfig.Audience_Secret_String; var claims = new List <Claim> { new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()), new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()), new Claim(JwtRegisteredClaimNames.Iss, issue), new Claim(JwtRegisteredClaimNames.Aud, audience) }; // 支持单用户多角色 claims.AddRange(tokenModel.Role.Split(",").Select(r => new Claim(ClaimTypes.Role, r))); // 密钥(SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报异常) var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken( issuer: issue, claims: claims, signingCredentials: creds ); var jwtHandler = new JwtSecurityTokenHandler(); var encodeJwt = jwtHandler.WriteToken(jwt); return(encodeJwt); }
public static void UseQuartzJobMildd(this IApplicationBuilder app, ITasksQzSvc tasksQzSvc, ISchedulerCenter schedulerCenter) { if (app == null) { throw new ArgumentNullException(nameof(app)); } try { if (Appsettings.App("Middleware", "QuartzNetJob", "Enabled").ToBoolReq()) { var allQzServices = tasksQzSvc.Query().Result; foreach (var item in allQzServices) { if (item.JobStatus == JobStatus.运行中) { var ResuleModel = schedulerCenter.AddScheduleJobAsync(item).Result; if (ResuleModel.Success) { Console.WriteLine($"QuartzNetJob{item.JobName}启动成功!"); } else { Console.WriteLine($"QuartzNetJob{item.JobName}启动失败!错误信息:{ResuleModel.Message}"); } } } } } catch (Exception e) { log.Error($"An error was reported when starting the job service.\n{e.Message}"); throw; } }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.App("Middleware", "SignalR", "Enabled").ToBoolReq()) { await _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()); } await _next(context); }
public static void ConfigureEventBus(this IApplicationBuilder App) { if (Appsettings.App(new string[] { "EventBus", "Enabled" }).ToBoolReq()) { var eventBus = App.ApplicationServices.GetRequiredService <IEventBus>(); eventBus.Subscribe <ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>(); } }
public RedisCacheManager() { var redisConfiguration = Appsettings.App("RedisCaching", "ConnectionString"); //获取连接字符串 if (string.IsNullOrWhiteSpace(redisConfiguration)) { throw new ArgumentException("redis config is empty", nameof(redisConfiguration)); } _redisConnenctionString = redisConfiguration; _redisConnection = GetRedisConnection(); }
public RedisCacheManager() { string redisConnectionConfiguration = Appsettings.App(new string[] { "AppSettings", "RedisCacheAOP", "ConnectionString" }); if (string.IsNullOrWhiteSpace(redisConnectionConfiguration)) { throw new ArgumentException("Redis config is empty.", nameof(redisConnectionConfiguration)); } redisConnectionString = redisConnectionConfiguration; redisConnection = GetRedisConnect(); }
public static void AddKafkaSetup(this IServiceCollection services, IConfiguration configuration) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "Kafka", "Enabled" }).ToBoolReq()) { services.Configure <KafkaOptions>(configuration.GetSection("kafka")); services.AddSingleton <IKafkaConnectionPool, KafkaConnectionPool>(); } }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.App("Middleware", "IPLog", "Enabled").ToBoolReq()) { // 过滤,只有接口 if (context.Request.Path.Value.Contains("api")) { //reuqest支持buff,否则body只能读取一次 context.Request.EnableBuffering(); try { // 存储请求数据 var request = context.Request; var requestInfo = JsonConvert.SerializeObject(new RequestInfo() { ClientIP = GetClientIP(context)?.Replace("::ffff:", ""), Url = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Path, Datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Week = DateHelper.GetWeek(), }); if (!string.IsNullOrEmpty(requestInfo)) { // 自定义log输出 //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("RequestIpInfoLog", new string[] { requestInfo + "," }, false); //}); SerilogServer.WriteLog("RequestIpInfoLog", new string[] { requestInfo + ", " }, false); // 这里读取过body Position是读取过几次 而此操作优于控制器先行 控制器只会读取Position为零次的 request.Body.Position = 0; } await _next(context); // 执行下一个中间件 } catch (Exception) { } } else { await _next(context); } } else { await _next(context); } }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.App("Middleware", "RequestResponseLog", "Enabled").ToBoolReq()) { // 过滤,只有接口 if (context.Request.Path.Value.Contains("api")) { context.Request.EnableBuffering(); Stream originalBody = context.Response.Body; try { // 存储请求数据 await RequestDataLog(context); using (var ms = new MemoryStream()) { context.Response.Body = ms; await _next(context); // 存储响应数据 ResponseDataLog(context.Response, ms); ms.Position = 0; await ms.CopyToAsync(originalBody); } } catch (Exception ex) { // 记录异常 //ErrorLogData(context.Response, ex); _logger.LogError(ex.Message + "" + ex.InnerException); } finally { context.Response.Body = originalBody; } } else { await _next(context); } } else { await _next(context); } }
/// <summary> /// 颁发JWT字符串 /// </summary> /// <param name="tokenModel"></param> /// <returns></returns> public static string IssueJwt(TokenModelJwt tokenModel) { string iss = Appsettings.App(new string[] { "Audience", "Issuer" }); string aud = Appsettings.App(new string[] { "Audience", "Audience" }); string secret = AppSecretConfig.Audience_Secret_String; //var claims = new Claim[] //old var claims = new List <Claim> { /* * 特别重要: * 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! * 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 */ new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Id.ToString()), new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间 new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()), new Claim(JwtRegisteredClaimNames.Iss, iss), new Claim(JwtRegisteredClaimNames.Aud, aud), //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法 }; // 可以将一个用户的多个角色全部赋予; // 作者:DX 提供技术支持; claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken( issuer: iss, claims: claims, signingCredentials: creds); var jwtHandler = new JwtSecurityTokenHandler(); var encodedJwt = jwtHandler.WriteToken(jwt); return(encodedJwt); }
public static void AddRabbitMQSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "RabbitMQ", "Enabled" }).ToBoolReq()) { services.AddSingleton <IRabbitMQPersistentConnection>(sp => { var logger = sp.GetRequiredService <ILogger <RabbitMQPersistentConnection> >(); var factory = new ConnectionFactory() { HostName = Appsettings.App(new string[] { "RabbitMQ", "Connection" }), DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Appsettings.App(new string[] { "RabbitMQ", "UserName" }))) { factory.UserName = Appsettings.App(new string[] { "RabbitMQ", "UserName" }); } if (!string.IsNullOrEmpty(Appsettings.App(new string[] { "RabbitMQ", "Password" }))) { factory.Password = Appsettings.App(new string[] { "RabbitMQ", "Password" }); } if (!string.IsNullOrEmpty(Appsettings.App(new string[] { "RabbitMQ", "Port" }))) { factory.Port = Appsettings.App(new string[] { "RabbitMQ", "Port" }).ToInt32Req(); } var retryCount = 5; if (!string.IsNullOrEmpty(Appsettings.App(new string[] { "RabbitMQ", "RetryCount" }))) { retryCount = Appsettings.App(new string[] { "RabbitMQ", "RetryCount" }).ToInt32Req(); } return(new RabbitMQPersistentConnection(factory, logger, retryCount)); }); } }
/// <summary> /// Cors 跨域资源共享 /// </summary> /// <param name="services"></param> public static void AddCorsSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } services.AddCors(c => { if (!Appsettings.App(new string[] { "Startup", "Cors", "EnableAllIPs" }).ToBoolReq()) { c.AddPolicy(Appsettings.App(new string[] { "Startup", "Cors", "PolicyName" }), policy => { policy .WithOrigins(Appsettings.App(new string[] { "Startup", "Cors", "IPs" }).Split(',')) .AllowAnyHeader() //Ensures that the policy allows any header. .AllowAnyMethod(); }); } else { //允许任意跨域请求 c.AddPolicy(Appsettings.App(new string[] { "Startup", "Cors", "PolicyName" }), policy => { policy .SetIsOriginAllowed((host) => true) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); } //.WithOrigins(Appsettings.App(new string[] { "Startup", "Cors", "IPs" }).Split(',')) //允许部分站点跨域请求 //.SetPreflightMaxAge(TimeSpan.FromSeconds(2520)) //添加预检请求过期时间 //.SetIsOriginAllowed(origin => true) //允许任何域 //.AllowAnyHeader() //允许任何头 //.AllowAnyMethod() //允许任何方式 //.AllowCredentials(); // 允许Cookie信息 }); }
public static void UseSeedDataMildd(this IApplicationBuilder app, MyContext myContext, string webRootPath) { if (app == null) { throw new ArgumentNullException(nameof(app)); } try { if (Appsettings.App("AppSettings", "SeedDBEnabled").ToBoolReq() || Appsettings.App("AppSettings", "SeedDBDataEnabled").ToBoolReq()) { DBSeed.SeedAsync(myContext, webRootPath).Wait(); } } catch (Exception e) { log.Error($"Error occured seeding the Database.\n{e.Message}"); throw; } }
public static void UseIpLimitMildd(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } try { if (Appsettings.App("Middleware", "IpRateLimit", "Enabled").ToBoolReq()) { app.UseIpRateLimiting(); } } catch (Exception e) { log.Error($"Error occured limiting ip rate.\n{e.Message}"); throw; } }
/// <summary> /// Redis缓存 /// </summary> /// <param name="services"></param> public static void AddRedisCacheSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } services.AddTransient <IRedisCache, RedisCache>(); services.AddSingleton <ConnectionMultiplexer>(sp => { //获取连接字符串 string redisConfiguration = Appsettings.App(new string[] { "Redis", "ConnectionString" }); var configuration = ConfigurationOptions.Parse(redisConfiguration, true); configuration.ResolveDns = true; return(ConnectionMultiplexer.Connect(configuration)); }); }
public static void UseMiniProfilerMildd(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } try { if (Appsettings.App("Startup", "MiniProfiler", "Enabled").ToBoolReq()) { // 性能分析 app.UseMiniProfiler(); } } catch (Exception e) { log.Error($"An error was reported when starting the MiniProfilerMildd.\n{e.Message}"); throw; } }
public static void AddAuthentication_Ids4Setup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } // 添加Identityserver4认证 services.AddAuthentication(o => { o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; o.DefaultChallengeScheme = nameof(ApiResponseHandler); o.DefaultForbidScheme = nameof(ApiResponseHandler); }) .AddJwtBearer(options => { options.Authority = Appsettings.App(new string[] { "Startup", "IdentityServer4", "AuthorizationUrl" }); options.RequireHttpsMetadata = false; options.Audience = Appsettings.App(new string[] { "Startup", "IdentityServer4", "ApiName" }); }) .AddScheme <AuthenticationSchemeOptions, ApiResponseHandler>(nameof(ApiResponseHandler), o => { }); }
public static void AddEventBusSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "EventBus", "Enabled" }).ToBoolReq()) { var subscriptionClientName = Appsettings.App(new string[] { "EventBus", "SubscriptionClientName" }); services.AddSingleton <IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); services.AddTransient <ProductPriceChangedIntegrationEventHandler>(); if (Appsettings.App(new string[] { "RabbitMQ", "Enabled" }).ToBoolReq()) { services.AddSingleton <IEventBus, EventBusRabbitMQ>(sp => { var rabbitMQPersistentConnection = sp.GetRequiredService <IRabbitMQPersistentConnection>(); var iLifetimeScope = sp.GetRequiredService <ILifetimeScope>(); var logger = sp.GetRequiredService <ILogger <EventBusRabbitMQ> >(); var eventBusSubcriptionsManager = sp.GetRequiredService <IEventBusSubscriptionsManager>(); var retryCount = 5; if (!string.IsNullOrEmpty(Appsettings.App(new string[] { "RabbitMQ", "RetryCount" }))) { retryCount = int.Parse(Appsettings.App(new string[] { "RabbitMQ", "RetryCount" })); } return(new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount)); }); } if (Appsettings.App(new string[] { "Kafka", "Enabled" }).ToBoolReq()) { services.AddHostedService <KafkaConsumerHostService>(); services.AddSingleton <IEventBus, EventBusKafka>(); } } }
/// <summary> /// MiniProfiler 接口执行时间分析 /// </summary> /// <param name="services"></param> public static void AddMiniProfilerSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "Startup", "MiniProfiler", "Enabled" }).ToBoolReq()) { // 3.x使用MiniProfiler,必须要注册MemoryCache服务 services.AddMiniProfiler(options => { //访问地址路由根目录;默认为:/mini-profiler-resources options.RouteBasePath = "/profiler"; //数据缓存时间 //(options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(60); //sql格式化设置 options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter(); //跟踪连接打开关闭 options.TrackConnectionOpenClose = true; //界面主题颜色方案;默认浅色 options.ColorScheme = StackExchange.Profiling.ColorScheme.Light; //.net core 3.0以上:对MVC过滤器进行分析 options.EnableMvcFilterProfiling = true; //对视图进行分析 options.EnableMvcViewProfiling = true; //设定弹出窗口的位置是左上角 options.PopupRenderPosition = StackExchange.Profiling.RenderPosition.Left; //设定在弹出的明细窗口里会显式Time With Children这列 options.PopupShowTimeWithChildren = true; // 可以增加权限 //options.ResultsAuthorize = request => request.HttpContext.User.IsInRole("Admin"); //options.UserIdProvider = request => request.HttpContext.User.Identity.Name; } ); } }
protected override void Load(Autofac.ContainerBuilder builder) { #region 带有接口的服务注册 #region AOP List <Type> aopList = new List <Type>(); if (Appsettings.App(new string[] { "AppSettings", "RedisCacheAOP", "Enabled" }).ObjToBool()) { builder.RegisterType <RedisCacheManager>().As(typeof(IRedisCacheManager)).SingleInstance(); builder.RegisterType <BlogRedisCacheAOP>(); aopList.Add(typeof(BlogRedisCacheAOP)); } if (Appsettings.App(new string[] { "AppSettings", "MemoryCacheAOP", "Enabled" }).ObjToBool()) { builder.RegisterType <Microsoft.Extensions.Caching.Memory.MemoryCache>().As(typeof(IMemoryCache)).SingleInstance(); builder.RegisterType <Helper.MemoryCache>().As(typeof(ICache)).SingleInstance(); builder.RegisterType <BlogCacheAOP>(); aopList.Add(typeof(BlogCacheAOP)); } if (Appsettings.App(new string[] { "AppSettings", "LogAOP", "Enabled" }).ObjToBool()) { builder.RegisterType <BlogLogAOP>(); aopList.Add(typeof(BlogLogAOP)); } #endregion // 注册泛型仓储 builder.RegisterGeneric(typeof(BaseRepository <>)).As(typeof(IBaseRepository <>)).InstancePerDependency(); // 注册服务 builder.RegisterType <AdvertisementService>().As <IAdvertisementService>() .InstancePerLifetimeScope() .EnableInterfaceInterceptors() .InterceptedBy(aopList.ToArray()); builder.RegisterType <BlogArticleService>().As <IBlogArticleService>() .InstancePerLifetimeScope() .EnableInterfaceInterceptors() .InterceptedBy(aopList.ToArray()); #endregion }
public static void AddNacosSetup(this IServiceCollection services, IConfiguration Configuration) { if (services == null) { throw new ArgumentNullException(nameof(services)); } // 在实际生产工作中 本地开发是不需要注册nacos的 所以根据环境变量去判断 // 比如 开发环境 dev 测试环境 test 生产 prod 只有这几种环境变量的时候才需要去注册nacos if (Appsettings.App(new string[] { "Startup", "Nacos", "Enabled" }).ToBoolReq()) { // 从当前配置取文件去注册naocs services.AddNacosV2Config(x => { x.ServerAddresses = JsonConfigSettings.NacosServerAddresses; x.EndPoint = ""; x.Namespace = JsonConfigSettings.NacosNamespace; x.DefaultTimeOut = JsonConfigSettings.NacosDefaultTimeOut; x.ListenInterval = JsonConfigSettings.ListenInterval; // swich to use http or rpc x.ConfigUseRpc = false; }); services.AddNacosV2Naming(x => { x.ServerAddresses = JsonConfigSettings.NacosServerAddresses; x.EndPoint = ""; x.Namespace = JsonConfigSettings.NacosNamespace; x.DefaultTimeOut = JsonConfigSettings.NacosDefaultTimeOut; x.ListenInterval = JsonConfigSettings.ListenInterval; // swich to use http or rpc x.NamingUseRpc = false; }); services.AddHostedService <NacosListenNamingTask>(); //增加服务注入,删除事件 // 监听nacos中的配置中心 如果有新配置变更 执行相关逻辑 services.AddHostedService <NacosListenConfigurationTask>(); //增加配置文件监听事件 } services.AddSingleton(Configuration); }
public static void UseSwaggerMildd(this IApplicationBuilder app, Func <Stream> streamHtml) { if (app == null) { throw new ArgumentNullException(nameof(app)); } app.UseSwagger(); app.UseSwaggerUI(c => { //根据版本名称倒序 遍历展示 var ApiName = Appsettings.App(new string[] { "Startup", "ApiName" }); typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}"); }); // 将swagger首页,设置成我们自定义的页面,记得这个字符串的写法:{项目名.index.html} if (streamHtml.Invoke() == null) { var msg = "index.html的属性,必须设置为嵌入的资源"; log.Error(msg); throw new Exception(msg); } c.IndexStream = streamHtml; if (Permissions.IsUseIds4) { c.OAuthClientId("blogadminjs"); } c.DefaultModelsExpandDepth(-1); // 不显示models c.RoutePrefix = ""; //路径配置,设置后直接输入IP就可以进入接口文档 }); }
public static void AddAppTableConfigSetup(this IServiceCollection services, IHostEnvironment env) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "Startup", "AppConfigAlert", "Enabled" }).ToBoolReq()) { if (env.IsDevelopment()) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); } #region 序配置 List <string[]> configInfos = new() { new string[] { "当前环境", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") }, new string[] { "当前的授权方案", Permissions.IsUseIds4 ? "Ids4" : "JWT" }, new string[] { "CORS跨域", Appsettings.App("Startup", "Cors", "EnableAllIPs") }, new string[] { "RabbitMQ消息列队", Appsettings.App("RabbitMQ", "Enabled") }, new string[] { "事件总线(必须开启消息列队)", Appsettings.App("EventBus", "Enabled") }, new string[] { "redis消息队列", Appsettings.App("Startup", "RedisMq", "Enabled") }, new string[] { "是否多库", Appsettings.App("MutiDBEnabled") }, new string[] { "读写分离", Appsettings.App("CQRSEnabled") }, }; new ConsoleTable() { TitleString = "Blog.Core 配置集", Columns = new string[] { "配置名称", "配置信息/是否启动" }, Rows = configInfos, EnableCount = false, Alignment = Alignment.Left, ColumnBlankNum = 4, TableStyle = TableStyle.Alternative }.Writer(ConsoleColor.Blue); Console.WriteLine(); #endregion 序配置 #region AOP List <string[]> aopInfos = new() { new string[] { "Redis缓存AOP", Appsettings.App("AppSettings", "RedisCachingAOP", "Enabled") }, new string[] { "内存缓存AOP", Appsettings.App("AppSettings", "MemoryCachingAOP", "Enabled") }, new string[] { "服务日志AOP", Appsettings.App("AppSettings", "LogAOP", "Enabled") }, new string[] { "事务AOP", Appsettings.App("AppSettings", "TranAOP", "Enabled") }, new string[] { "Sql执行AOP", Appsettings.App("AppSettings", "SqlAOP", "OutToLogFile", "Enabled") }, new string[] { "Sql执行AOP控制台输出", Appsettings.App("AppSettings", "SqlAOP", "OutToConsole", "Enabled") }, }; new ConsoleTable { TitleString = "AOP", Columns = new string[] { "配置名称", "配置信息/是否启动" }, Rows = aopInfos, EnableCount = false, Alignment = Alignment.Left, ColumnBlankNum = 7, TableStyle = TableStyle.Alternative }.Writer(ConsoleColor.Blue); Console.WriteLine(); #endregion AOP #region 中间件 List <string[]> MiddlewareInfos = new() { new string[] { "API请求记录中间件", Appsettings.App("Middleware", "RecordAccessLogs", "Enabled") }, new string[] { "IP记录中间件", Appsettings.App("Middleware", "IPLog", "Enabled") }, new string[] { "请求响应日志中间件", Appsettings.App("Middleware", "RequestResponseLog", "Enabled") }, new string[] { "SingnalR实时发送请求数据中间件", Appsettings.App("Middleware", "SignalR", "Enabled") }, new string[] { "IP限流中间件", Appsettings.App("Middleware", "IpRateLimit", "Enabled") }, new string[] { "性能分析中间件", Appsettings.App("Startup", "MiniProfiler", "Enabled") }, new string[] { "Consul注册服务", Appsettings.App("Middleware", "Consul", "Enabled") }, }; new ConsoleTable { TitleString = "中间件", Columns = new string[] { "配置名称", "配置信息/是否启动" }, Rows = MiddlewareInfos, EnableCount = false, Alignment = Alignment.Left, ColumnBlankNum = 3, TableStyle = TableStyle.Alternative }.Writer(ConsoleColor.Blue); Console.WriteLine(); #endregion 中间件 } }
public static void AddAppConfigSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (Appsettings.App(new string[] { "Startup", "AppConfigAlert", "Enabled" }).ToBoolReq()) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); //避免乱码 Console.WriteLine("************ WebApi Config Set *****************"); ConsoleHelper.WriteSuccessLine("Current environment: " + Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); // 授权策略方案 if (Permissions.IsUseIds4) { ConsoleHelper.WriteSuccessLine($"Current authorization scheme: " + (Permissions.IsUseIds4 ? "Ids4" : "JWT")); } else { Console.WriteLine($"Current authorization scheme: " + (Permissions.IsUseIds4 ? "Ids4" : "JWT")); } // Redis缓存AOP if (!Appsettings.App(new string[] { "AppSettings", "RedisCachingAOP", "Enabled" }).ToBoolReq()) { Console.WriteLine($"Redis Caching AOP: False"); } else { ConsoleHelper.WriteSuccessLine($"Redis Caching AOP: True"); } // 内存缓存AOP if (!Appsettings.App(new string[] { "AppSettings", "MemoryCachingAOP", "Enabled" }).ToBoolReq()) { Console.WriteLine($"Memory Caching AOP: False"); } else { ConsoleHelper.WriteSuccessLine($"Memory Caching AOP: True"); } // 服务日志AOP if (!Appsettings.App(new string[] { "AppSettings", "LogAOP", "Enabled" }).ToBoolReq()) { Console.WriteLine($"Service Log AOP: False"); } else { ConsoleHelper.WriteSuccessLine($"Service Log AOP: True"); } // 事务AOP if (!Appsettings.App(new string[] { "AppSettings", "TranAOP", "Enabled" }).ToBoolReq()) { Console.WriteLine($"Transaction AOP: False"); } else { ConsoleHelper.WriteSuccessLine($"Transaction AOP: True"); } // 数据库Sql执行AOP if (!Appsettings.App(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ToBoolReq()) { Console.WriteLine($"DB Sql AOP: False"); } else { ConsoleHelper.WriteSuccessLine($"DB Sql AOP: True"); } // SingnalR发送数据 if (!Appsettings.App(new string[] { "Middleware", "SignalR", "Enabled" }).ToBoolReq()) { Console.WriteLine($"SignalR send data: False"); } else { ConsoleHelper.WriteSuccessLine($"SignalR send data: True"); } // IP限流 if (!Appsettings.App("Middleware", "IpRateLimit", "Enabled").ToBoolReq()) { Console.WriteLine($"IpRateLimiting: False"); } else { ConsoleHelper.WriteSuccessLine($"IpRateLimiting: True"); } // 性能分析 if (!Appsettings.App("Startup", "MiniProfiler", "Enabled").ToBoolReq()) { Console.WriteLine($"MiniProfiler: False"); } else { ConsoleHelper.WriteSuccessLine($"MiniProfiler: True"); } // CORS跨域 if (!Appsettings.App("Startup", "Cors", "EnableAllIPs").ToBoolReq()) { Console.WriteLine($"EnableAllIPs For CORS: False"); } else { ConsoleHelper.WriteSuccessLine($"EnableAllIPs For CORS: True"); } // redis消息队列 if (!Appsettings.App("Startup", "RedisMq", "Enabled").ToBoolReq()) { Console.WriteLine($"Redis MQ: False"); } else { ConsoleHelper.WriteSuccessLine($"Redis MQ: True"); } // Consul 注册服务 if (!Appsettings.App("Middleware", "Consul", "Enabled").ToBoolReq()) { Console.WriteLine($"Consul service: False"); } else { ConsoleHelper.WriteSuccessLine($"Consul service: True"); } // 多库 if (!Appsettings.App(new string[] { "MutiDBEnabled" }).ToBoolReq()) { Console.WriteLine($"Is multi-DataBase: False"); } else { ConsoleHelper.WriteSuccessLine($"Is multi-DataBase: True"); } // 读写分离 if (!Appsettings.App(new string[] { "CQRSEnabled" }).ToBoolReq()) { Console.WriteLine($"Is CQRS: False"); } else { ConsoleHelper.WriteSuccessLine($"Is CQRS: True"); } Console.WriteLine(); } }
/// <summary> /// 应用程序运行时将服务添加到容器中 /// </summary> /// <param name="services"></param> /// <remarks> /// 权重:AddSingleton→AddTransient→AddScoped /// AddSingleton的生命周期:项目启动-项目关闭 相当于静态类 只会有一个 /// AddScoped 的生命周期:请求开始-请求结束 在这次请求中获取的对象都是同一个 /// AddTransient的生命周期:请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个 /// </remarks> public void ConfigureServices(IServiceCollection services) { services.AddSingleton(new Appsettings(Configuration)); services.AddSingleton(new LogLock(Env.ContentRootPath)); //接口请求日志 services.AddSingleton(new SerilogServer(Env.ContentRootPath)); //接口请求日志 services.AddMemoryCacheSetup(); services.AddRedisCacheSetup(); services.AddSqlsugarSetup(); services.AddDbSetup(); services.AddAutoMapperSetup(); services.AddCorsSetup(); services.AddMiniProfilerSetup(); services.AddSwaggerSetup(); services.AddJobSetup(); services.AddHttpContextSetup(); // services.AddAppConfigSetup(); services.AddAppTableConfigSetup(Env);//表格打印配置 services.AddHttpApi(); services.AddRedisInitMqSetup(); //services.AddHstsSetup(); // 生产环境中使用 //services.AddAntiforgerySetup(); //防止CSRF攻击 services.AddRabbitMQSetup(); services.AddKafkaSetup(Configuration); services.AddEventBusSetup(); services.AddNacosSetup(Configuration); Permissions.IsUseIds4 = Appsettings.App(new string[] { "Startup", "IdentityServer4", "Enabled" }).ToBoolReq(); // 确保从ids4认证中心返回的ClaimType不被更改,不使用Map映射 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // 授权+认证 (jwt or ids4) services.AddAuthorizationSetup(); if (Permissions.IsUseIds4) { services.AddAuthentication_Ids4Setup(); } else { services.AddAuthentication_JWTSetup(); } services.AddIpPolicyRateLimitSetup(Configuration); services.AddSignalR(hubOptions => { //注意:建议 服务端clientTimeoutInterval 的值是 客户端keepAliveIntervalInmillisecods 的两倍,从而保证不进服务器端的 OnDisconnectedAsync 回调,即不掉线 hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(30); //服务器端配置30s没有收到客户端发送的消息,则认为客户端已经掉线 }).AddNewtonsoftJsonProtocol(); //配置可以同步请求读取流数据 services.Configure <KestrelServerOptions>(x => x.AllowSynchronousIO = true) .Configure <IISServerOptions>(x => x.AllowSynchronousIO = true); //services.AddRouting(options => //{ // options.LowercaseUrls = true; //小写url的路由 //}); services.AddDistributedMemoryCache(); services.AddSession(); services.AddHttpPollySetup(); //启用控制器 services.AddControllers(options => { if (Appsettings.App(new string[] { "RSACryption", "Enabled" }).ToBoolReq()) { options.Filters.Add(typeof(DataDecryptFilter)); //数据解密过滤器 } //全局XSS过滤器 //options.Filters.Add(typeof(XSSFilterAttribute)); //全局给post Action都开启了防止CSRF攻击,配合services.AddAntiforgerySetup()使用 //options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); //全局配置防止SQL注入过滤(或者在控制器方法上添加[AntiSqlInjectFilter]) //options.Filters.Add(typeof(AntiSqlInjectFilter)); // 全局异常过滤 options.Filters.Add(typeof(GlobalExceptionsFilter)); // 全局路由权限公约 //o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention()); // 全局路由前缀,统一修改路由 options.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name))); }) //全局配置Json序列化处理 .AddNewtonsoftJson(options => { //忽略循环引用,如果设置为Error,则遇到循环引用的时候报错 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //json中属性开头字母小写的驼峰命名 options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //日期格式化 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //如果字段为null,该字段会依然返回到json中。比如"name":null options.SerializerSettings.NullValueHandling = NullValueHandling.Include; }); //.ConfigureApiBehaviorOptions(options => //{ // options.SuppressConsumesConstraintForFormFileParameters = true; // options.SuppressInferBindingSourcesForParameters = true; // options.SuppressModelStateInvalidFilter = true;//true:禁用自动 400 行为 // options.SuppressMapClientErrors = true; // options.ClientErrorMapping[404].Link = // "https://*/404"; //}); services.Replace(ServiceDescriptor.Transient <IControllerActivator, ServiceBasedControllerActivator>()); _services = services; //支持编码大全 例如:支持 System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030") Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyContext myContext, ITasksQzSvc tasksQzSvc, ISchedulerCenter schedulerCenter, IHostApplicationLifetime lifetime) { // Ip限流,尽量放管道外层 app.UseIpLimitMildd(); // 记录请求与返回数据 app.UseReuestResponseLog(); // 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流) app.UseRecordAccessLogsMildd(); // signalr app.UseSignalRSendMildd(); // 记录ip请求 app.UseIPLogMildd(); // 查看注入的所有服务 app.UseAllServicesMildd(_services); if (env.IsDevelopment()) { // 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // 在非开发环境中,使用HTTP严格安全传输(or HSTS) 对于保护web安全是非常重要的。 // 强制实施 HTTPS 在 ASP.NET Core,需要配合 app.UseHttpsRedirection()与services.AddHstsSetup() //app.UseHsts(); // HSTS 中间件(UseHsts)用于向客户端发送 HTTP 严格传输安全协议(HSTS)标头 } // 自定义Swagger权限拦截中间件,放到Swagger中间件之前 app.UseSession(); app.UseSwaggerAuthorized(); // 封装Swagger展示 app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Xu.WebApi.index.html")); // ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓ // CORS跨域 app.UseCors(Appsettings.App(new string[] { "Startup", "Cors", "PolicyName" })); // 重定向中间件,用于将 HTTP 请求重定向到 HTTPS //app.UseHttpsRedirection(); // 使用静态文件 DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); app.UseDefaultFiles(defaultFilesOptions); // 默认使用wwwroot静态文件 app.UseStaticFiles(); // 使用cookie app.UseCookiePolicy(); // 返回错误码 app.UseStatusCodePages(); // Routing app.UseRouting(); // 这种自定义授权中间件,可以尝试,但不推荐 // app.UseJwtTokenAuth(); // 先开启认证--验证当前请求的用户,并设置HttpContext.User,当OAuth callbacks时,会中止执行下一个中间件。 app.UseAuthentication(); // 然后是授权中间件 app.UseAuthorization(); // 开启性能分析 app.UseMiniProfilerMildd(); // 开启异常中间件,要放到最后 app.UseExceptionHandlerMidd(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapHub <ChatHub>("/api/chatHub"); }); // 生成种子数据 app.UseSeedDataMildd(myContext, Env.WebRootPath); // 开启QuartzNetJob调度服务 app.UseQuartzJobMildd(tasksQzSvc, schedulerCenter); // 服务注册 app.UseConsulMildd(Configuration, lifetime); // 事件总线,订阅服务 app.ConfigureEventBus(); }