示例#1
0
            /// <summary>
            /// 重写Invoke
            /// </summary>
            /// <param name="context"></param>
            /// <param name="next"></param>
            /// <returns></returns>
            public override async Task Invoke(AspectContext context, AspectDelegate next)
            {
                var config = context.ServiceProvider.GetService(typeof(IConfiguration)) as IConfiguration;

                var prefix = config["RedisPrefix:DistributedLock"];

                if (string.IsNullOrWhiteSpace(prefix))
                {
                    throw new H_Exception("请配置分布式锁名称的前缀字符");
                }

                using (var redisLock = RedisHelper.Lock(prefix + _lockName, _timeoutSeconds, _autoDelay))
                {
                    if (redisLock == null)
                    {
                        H_Log.Error("系统异常:开启Redis分布式锁失败");
                        throw new H_Exception("系统异常");
                    }

                    //if (redisLock == null) throw new H_Exception("系统异常"); //开启分布式锁超时 //对象为null,不占资源 ,编译后的代码没有fianlly,不执行dispose()方法
                    //锁超时是什么意思呢?如果一个得到锁的线程在执行任务的过程中挂掉,来不及显式地释放锁,这块资源将会永远被锁住,别的线程再也别想进来。

                    //所以,setnx的key必须设置一个超时时间,以保证即使没有被显式释放,这把锁也要在一定时间后自动释放。
                    await next(context);
                }
            }
示例#2
0
        /// <summary>
        /// 控制器中的操作执行后调用此方法 再执行H_ResultFilter全局过滤器
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            object result = null; //EmptyResult对应null

            if (context.Result is ObjectResult)
            {
                result = (context.Result as ObjectResult)?.Value;
            }
            else if (context.Result is JsonResult)
            {
                result = (context.Result as JsonResult)?.Value;
            }

            var userId = context.HttpContext.User.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Sid)?.Value;

            var descriptor = context.ActionDescriptor as ControllerActionDescriptor;

            if (!descriptor.MethodInfo.CustomAttributes.Any(x => x.AttributeType == typeof(IgnoreExcutedLogAttribute)))
            {
                H_Log.Info(new LogNote
                {
                    Location = HttpContext.Request.Path.Value,
                    Data     = result,
                    TraceId  = context.HttpContext.TraceIdentifier,
                    UserId   = userId,
                    Extra    = "响应结果"
                });
            }

            base.OnActionExecuted(context);
        }
示例#3
0
        public async Task <LoginOutput> LoginByAccountPwd(LoginByAccountPwdInput input)
        {
            string ip = HttpContext.GetIp();

            H_Log.Info(new LogNote()
            {
                Location = "LoginByAccountPwd",
                Data     = input,
                TraceId  = HttpContext.TraceIdentifier,
                IP       = ip,
                Extra    = "登录请求"
            });

            var result = await _loginAppService.LoginByAccountPwd(input, ip);

            H_Log.Info(new LogNote()
            {
                Location = "LoginByAccountPwd",
                Data     = result,
                TraceId  = HttpContext.TraceIdentifier,
                IP       = ip,
                Extra    = "登录返回"
            });

            return(result);
        }
示例#4
0
        //public IOptionsSnapshot<H_AppSettingsConfig> AppsettingsOptions { get; set; } //属性注入必须public IOptionsSnapshot修改即更新  和IConfiguration效果一样  热更新

        /// <summary>
        /// 控制器中的操作执行之前调用此方法(先执行这个方法 再执行模型验证)
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var userId = User.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Sid)?.Value; //Security Identifiers安全标识符

            var jti = User.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Jti)?.Value;

            var ip = context.HttpContext.GetIp();

            var servicesParams = context.ActionDescriptor.Parameters.Where(a => a.BindingInfo.BindingSource == BindingSource.Services).Select(a => a.Name);

            H_Log.Info(new LogNote
            {
                Location = context.HttpContext.Request.Path.Value,
                Data     = servicesParams.Any() ? context.ActionArguments.Where(a => !servicesParams.Contains(a.Key)) : context.ActionArguments,
                TraceId  = context.HttpContext.TraceIdentifier,
                UserId   = userId,
                IP       = ip,
                Extra    = "请求信息"
            });

            var cache = GetCacheUser(userId, jti);

            //if (ip != cache.Ip) throw new H_Exception("请重新登录", nameof(H_Error.E100004).GetErrorCode());

            CheckAuth(context, cache.AuthNums);

            var currentUser = context.HttpContext.RequestServices.GetService(typeof(ICurrentUser)) as CurrentUser;

            currentUser = cache.Adapt(currentUser);

            if (currentUser.Id == 2)
            {
                var method = context.HttpContext.Request.Method.ToLower();

                var isLogout = context.HttpContext.Request.Path.Value == "/CurrentUser/Logout";

                if (!isLogout)
                {
                    if (method.Equals("post") || method.Equals("put") || method.Equals("delete"))
                    {
                        throw new H_Exception("游客账户,无法进行数据操作");
                    }
                }
            }

            base.OnActionExecuting(context);
        }
        //静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。

        //静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存。
        /// <summary>
        /// 异常处理,不会处理eventbus中的异常
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private static async Task Invoke(HttpContext context)
        {
            context.Response.StatusCode  = StatusCodes.Status200OK;
            context.Response.ContentType = "application/json";

            var response = new H_Response {
                Success = false
            };

            var ex = context.Features.Get <IExceptionHandlerFeature>().Error;

            if (ex is H_Exception exception)
            {
                response.ErrorCode = exception.Code;
                response.ErrorMsg  = exception.Message;
            }
            else if (ex is AspectInvocationException aspectException)
            {
                response.ErrorMsg = aspectException.InnerException?.Message;
            }
#if DEBUG  //开发环境 能看具体错误
            else
            {
                response.ErrorMsg = ex.Message;
            }
#endif
            if (string.IsNullOrWhiteSpace(response.ErrorMsg))
            {
                response.ErrorMsg = "系统异常";
            }

            H_Log.Error(ex, new LogNote()
            {
                Location = context.Request.Path.Value,
                TraceId  = context.TraceIdentifier,
                Extra    = "系统异常信息"
            }); //异常信息,记录到日志中

            var options = new JsonSerializerOptions
            {
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, //解决中文乱码
                PropertyNamingPolicy = null                            //PropertyNamingPolicy = JsonNamingPolicy.CamelCase //开头字母小写 默认
            };

            await context.Response.WriteAsync(JsonSerializer.Serialize(response, options), Encoding.UTF8);
        }
        /// <summary>
        /// 异常处理,不会处理eventbus中的异常
        /// </summary>
        /// <param name="context"></param>
        public override void OnException(ExceptionContext context)
        {
            var ex = context.Exception;

            var response = new H_Response {
                Success = false
            };

            if (ex is H_Exception exception)
            {
                response.ErrorCode = exception.Code;
                response.ErrorMsg  = exception.Message;
            }
            else if (ex is AspectInvocationException aspectException)
            {
                response.ErrorMsg = aspectException.InnerException?.Message;
            }
#if DEBUG  //开发环境 能看具体错误
            else
            {
                response.ErrorMsg = ex.Message;
            }
#endif


            if (string.IsNullOrWhiteSpace(response.ErrorMsg))
            {
                response.ErrorMsg = "系统异常";
            }

            context.Result = new JsonResult(response);

            H_Log.Error(ex, new LogNote()
            {
                Location = context.HttpContext.Request.Path.Value,
                TraceId  = context.HttpContext.TraceIdentifier,
                Extra    = "系统异常信息"
            });                        //异常信息,记录到日志中

            base.OnException(context); //返回结果 不会经过ResultFilter
        }
        /// <summary>
        /// 用于配置中间件,以构建请求处理流水线
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <param name="appSettings"></param>
        /// <returns></returns>
        internal static IApplicationBuilder Configure(this IApplicationBuilder app, IHostEnvironment env, H_AppSettings appSettings)
        {
            #region DevEnvironment

            if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint($"{appSettings.Swagger.Name}/swagger.json", appSettings.Swagger.Name);
                });

                app.UseCors(x => x.AllowCredentials().AllowAnyMethod().AllowAnyHeader().WithOrigins(appSettings.CorsUrls));
            }

            #endregion

            app.UseSerilogRequestLogging();

            #region Nginx

            // Nginx 获取ip
            app.UseForwardedHeaders(new ForwardedHeadersOptions()
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            #endregion


            #region 异常中间件

            // app.UseExceptionMiddleware();

            #endregion


            #region 文件信息
            //使用默认文件夹wwwroot
            app.UseStaticFiles();

            //文件访问权限
            app.UseWhen(a => a.Request.Path.Value.Contains(appSettings.FilePath.ExportExcelPath) || a.Request.Path.Value.Contains("file_template"), b => b.UseMiddleware <StaticFileMiddleware>());


            //创建文件夹,保存导出的excel文件
            if (!Directory.Exists(appSettings.FilePath.ExportExcelPath))
            {
                Directory.CreateDirectory(appSettings.FilePath.ExportExcelPath);
            }

            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider        = new PhysicalFileProvider(appSettings.FilePath.ExportExcelPath),
                RequestPath         = appSettings.RequestPath.ExportExcel,
                ContentTypeProvider = new FileExtensionContentTypeProvider(new Dictionary <string, string>
                {
                    { ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }
                })
            });

            ////创建文件夹,保存头像文件
            //if (!Directory.Exists(appSettings.FilePath.AvatarPath))
            //{
            //    Directory.CreateDirectory(appSettings.FilePath.AvatarPath);
            //}

            //app.UseStaticFiles(new StaticFileOptions()
            //{
            //    FileProvider = new PhysicalFileProvider(appSettings.FilePath.AvatarPath),
            //    RequestPath = appSettings.RequestPath.AvatarFile
            //});
            #endregion


            #region 路由&权限

            app.UseRouting();

            //权限 .net core3.0需要放UseRouting后面
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            #endregion


            var projectName = Process.GetCurrentProcess().ProcessName;

            //使用Zookeeper自动分配管理WorkerId,解决时间回退问题和自动分配问题
            new IdHelperBootstrapper()
            .UseZookeeper(appSettings.ZookeeperUrl, 200, projectName)
            .Boot();

            H_Log.Info($"SnowflakeIdInfo ---> WorkId:{IdHelper.WorkerId},WorkTime:{DateTime.Now}");

            return(app);
        }