public CurrentTenantInfo GetCurrentTenantInfo()
        {
            CurrentTenantInfo currentTenantInfo = httpContextAccessor.HttpContext.Items["CurrentTenantInfo"] as CurrentTenantInfo;

            if (currentTenantInfo == null)
            {
                throw new FriendlyException()
                      {
                          ExceptionCode    = 400,
                          ExceptionMessage = $"CurrentTenantInfo is null."
                      };
            }
            return(currentTenantInfo);
        }
        public CurrentTenantInfo ReadCurrentTenantInfo()
        {
            CurrentTenantInfo currentTenantInfo = new CurrentTenantInfo();

            if (httpContextAccessor.HttpContext.User != null &&
                httpContextAccessor.HttpContext.User.Identity.IsAuthenticated) //external
            {
                ClaimsPrincipal claimsPrincipal = httpContextAccessor.HttpContext.User;
                var             subject         = claimsPrincipal.Claims.FirstOrDefault(w => w.Type == "role");
                currentTenantInfo.TenantCode = subject.Value;
            }
            else  //internal
            {
                //currentTenantInfo.CurrentTenantCode = httpContextAccessor.HttpContext.Request.Headers["CurrentTenantCode"].FirstOrDefault();
                currentTenantInfo.TenantCode = "CMB";
            }
            return(currentTenantInfo);
        }
        public async Task Invoke(HttpContext context)
        {
            CurrentTenantInfo currentTenantInfo = _currentTenantInfoProvider.ReadCurrentTenantInfo();

            context.Items.Add("CurrentTenantInfo", currentTenantInfo);
            currentUserInfo = _currentUserInfoProvider.ReadCurrentUserInfo();
            context.Items.Add("CurrentUserInfo", currentUserInfo);


            NLog.LogEventInfo requestLogEvent = new NLog.LogEventInfo(NLog.LogLevel.Trace, "ApiRequestLogger", "Invoke");
            requestLogEvent.Properties["RequestLogID"]       = Guid.NewGuid().ToString();
            requestLogEvent.Properties["RequestTimestamp"]   = DateTime.UtcNow;
            requestLogEvent.Properties["RequestMethod"]      = context.Request.Method;
            requestLogEvent.Properties["RequestUrl"]         = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}?{context.Request.QueryString}";//context.Request.GetDisplayUrl()
            requestLogEvent.Properties["RequestContentType"] = context.Request.ContentType;
            requestLogEvent.Properties["RequestBody"]        = await GetRequestBody(context.Request);

            requestLogEvent.Properties["RequestUser"]   = currentUserInfo == null ? "" : currentUserInfo.UserCode + " " + currentUserInfo.UserName;
            requestLogEvent.Properties["RequestTenant"] = currentTenantInfo == null ? "" : currentTenantInfo.TenantCode;
            requestLogEvent.Properties["HasError"]      = false;
            var originalBodyStream = context.Response.Body;

            using (var responseBody = new MemoryStream())
            {
                context.Response.Body = responseBody;
                try
                {
                    await _next(context);
                }
                catch (Exception ex)
                {
                    context.Response.ContentType = "application/json";
                    var exceptionResponse = "";
                    FriendlyException friendlyException = ex as FriendlyException;
                    if (friendlyException != null)
                    {
                        context.Response.StatusCode                = friendlyException.HttpStatusCode;
                        requestLogEvent.Properties["HasError"]     = true;
                        requestLogEvent.Properties["ErrorMessage"] = friendlyException.ExceptionMessage;
                        exceptionResponse = JsonConvert.SerializeObject(new { FriendlyExceptionMessage = friendlyException.ExceptionMessage });
                    }
                    else
                    {
                        context.Response.StatusCode                   = (int)HttpStatusCode.InternalServerError;
                        requestLogEvent.Properties["HasError"]        = true;
                        requestLogEvent.Properties["ErrorMessage"]    = ex.Message;
                        requestLogEvent.Properties["ErrorStackTrace"] = ex.StackTrace;
                        if (ex.InnerException != null)
                        {
                            requestLogEvent.Properties["ErrorMessage"]    = requestLogEvent.Properties["ErrorMessage"] + ";\n InnerExceptionMessage: " + ex.InnerException.Message;
                            requestLogEvent.Properties["ErrorStackTrace"] = requestLogEvent.Properties["ErrorMessage"] + ";\n InnerExceptionStackTrace: " + ex.InnerException.StackTrace;
                        }

                        exceptionResponse = JsonConvert.SerializeObject(new {
                            FriendlyExceptionMessage = $"未知异常,异常ID为{requestLogEvent.Properties["RequestLogID"]},请联系管理员处理。"
                        });
                    }

                    await context.Response.WriteAsync(exceptionResponse);
                }
                requestLogEvent.Properties["ResponseCode"]        = context.Response.StatusCode.ToString();
                requestLogEvent.Properties["ResponseContentType"] = context.Response.ContentType;
                requestLogEvent.Properties["ResponseBody"]        = await GetResponseBody(context.Response);

                await responseBody.CopyToAsync(originalBodyStream);
            }
            requestLogEvent.Properties["ResponseTimestamp"] = DateTime.UtcNow;
            requestLogEvent.Properties["ExecuteDuration"]   = (int)(Convert.ToDateTime(requestLogEvent.Properties["ResponseTimestamp"]) -
                                                                    Convert.ToDateTime(requestLogEvent.Properties["RequestTimestamp"])).TotalMilliseconds;
            requestLogger.Log(requestLogEvent);
            //NLog.Logger generalLogger = NLog.LogManager.GetLogger("GeneralLogger");
            //generalLogger.Info("testlog");
        }