• asp.net core ActionExecutedContext 获取Request.Body内容


    实体类:

     public class ApiActionDescriptorModel:ICloneable
        {
            
            public string ActionName { get; set; } 
    
            public string ControllerName { get; set; } 
    
            public ApiParameterDescriptorModel[] Parameters { get; set; } 
    
            public ApiReturnAttributeModel[] apiReturnAttributes { get; set; } 
    
            public string RequestIp { get; set; } 
    
            public string HttpMethod { get; set; } 
    
            public string RequestPort { get; set; }
    
            public long ExecutTime { get; set; } 
    
            public string Operator { get; set; } 
    
            public DateTime OperaTime { get; set; } 
    
            public string RequestBody { get; set; } 
    
            public string QueryString { get; set; }
            
            public string ResposeBody { get; set; } 
    
            public int ResposeStatusCode { get; set; } 
    
            public string UserId { get; set; }
    
            public object Clone()
            {
                return new ApiActionDescriptorModel
                {
                    ActionName = this.ActionName,
                    RequestIp = this.RequestIp,
                    HttpMethod = this.HttpMethod,
                    RequestPort = this.RequestPort,
                    ExecutTime = this.ExecutTime,
                    Parameters = this.Parameters.Select(t => (ApiParameterDescriptorModel)t.Clone()).ToArray()
                };
            }
        }
    

      过滤器:

    public class ExceptionFilter : IExceptionFilter
        {
            [Import]
            private ILoggerHelper loggerHelper { get; set; }
    
            public ExceptionFilter(IoC ioc) 
            {
                ioc.Compose(this);
            }
    
            public void OnException(ExceptionContext context)
            {
                if (context.ExceptionHandled == false)
                {
                    var jsonobj = Dr.Soc.Common.Helpers.JsonResult.Error(context.Exception.Message);
                    context.Result = new JsonResult(jsonobj);
                }
                loggerHelper.Error($"全局捕获异常:" + context.Exception.ToString()+"====="+
                    "入参参数:"+ GetExceptionRequestBody(context)+context?.HttpContext?.Request?.QueryString);
                
                context.ExceptionHandled = true;
            }
    
            public Task OnExceptionAsync(ExceptionContext context)
            {
                OnException(context);
                return Task.CompletedTask;
            }
    
            private string GetExceptionRequestBody(ExceptionContext context)
            {
                string requestBody = "";
                if (context != null)
                {
                    var request = context?.HttpContext?.Request;
                    if (request != null)
                    {
                        request.Body.Position = 0;
                        StreamReader stream = new StreamReader(request.Body);
                        requestBody = stream.ReadToEnd();
                        request.Body.Position = 0;
                    }
                }
                return requestBody;
            }
    
        }
    

      

     public class ActionFilter : IActionFilter
        {
            private Stopwatch timer;
    
            [Import]
            private IAduitService aduitService { get; set; }
    
            public ActionFilter(IoC ioc)
            {
                ioc.Compose(this);
            }
    
            public void OnActionExecuting(ActionExecutingContext context)
            {
                this.timer = new Stopwatch();
                this.timer.Start();
            }
    
            public void OnActionExecuted(ActionExecutedContext context)
            {
                this.timer.Stop();
                aduitService.HandleApiAction(GetActionDescriptor(context));
            }
    
            private ApiActionDescriptorModel GetActionDescriptor(ActionExecutedContext context)
            {
                ApiActionDescriptorModel descriptor = new ApiActionDescriptorModel();
       
                var userInfo= ((System.Security.Claims.ClaimsIdentity)context.HttpContext.User.Identity).Claims?.ToList();
                if (context != null)
                {
                    descriptor.ActionName = ((ControllerActionDescriptor)context.ActionDescriptor)?.ActionName;
                    descriptor.ControllerName = ((ControllerActionDescriptor)context.ActionDescriptor)?.ControllerName;
                    descriptor.RequestIp = context.HttpContext.Request.Host.Host.ToString();
                    descriptor.RequestPort = context.HttpContext.Request.Host.Port.ToString();
                    descriptor.HttpMethod = context.HttpContext.Request.Method.ToString();
                    descriptor.ExecutTime = this.timer.ElapsedMilliseconds;
                    descriptor.Operator = userInfo?.Where(t => t.Type == "UserName")?.FirstOrDefault()?.Value;
                    descriptor.UserId = userInfo?.Where(t => t.Type == "UserId")?.FirstOrDefault()?.Value;
                    descriptor.OperaTime = DateTime.Now;
                    descriptor.RequestBody = ReadActionExcutedRequestBody(context);
                    descriptor.QueryString = context.HttpContext.Request?.QueryString.ToString();
                    descriptor.ResposeBody = GetActionExcutedResponseBody(context);
                    descriptor.ResposeStatusCode = context.HttpContext.Response.StatusCode;
                }
    
                return descriptor;
            }
    
            private string ReadActionExcutedRequestBody(ActionExecutedContext context)
            {
                string requestBody = "";
                if (context != null)
                {
                    var request = context.HttpContext.Request;
                    request.Body.Position = 0;
                    StreamReader stream = new StreamReader(request.Body);
                    requestBody = stream.ReadToEnd();
                    request.Body.Position = 0;
                }
                return requestBody;
            }
    
            private string GetActionExcutedResponseBody(ActionExecutedContext context)
            {
                string responseBody = "";
                if (context.Result != null)
                {
                    if (context.Result is ObjectResult)
                        responseBody = JsonConvert.SerializeObject(((ObjectResult)context.Result).Value);
                    if (context.Result is JsonResult)
                        responseBody = JsonConvert.SerializeObject(((JsonResult)context.Result).Value);
                }
                return responseBody;
            }
        }
    

    在startup中注册:

    app.Use(next => new RequestDelegate(
                    async context =>
                    {
                        context.Request.EnableBuffering();
                        await next(context);
                    }
                    ));
    

      就可以在请求之后获取到请求体了。

    public async Task<bool> HandleApiAction(ApiActionDescriptorModel apiActionDescriptorModel)
            {
                bool result = false;
                var cacheAuditRule = auditRuleLoader.GetAllAuditRule();
                try
                {
                    if (cacheAuditRule == null || cacheAuditRule.Count == 0) return result;
    
                    if (string.IsNullOrEmpty(apiActionDescriptorModel?.RequestBody)
                    || string.IsNullOrEmpty(apiActionDescriptorModel?.ActionName)
                    || string.IsNullOrEmpty(apiActionDescriptorModel?.ControllerName)
                    || string.IsNullOrEmpty(apiActionDescriptorModel?.HttpMethod)) return result;
    
                    List<AuditModel> list = HandleApiAction(apiActionDescriptorModel, cacheAuditRule);
    
                    if (list == null || list.Count == 0) return result;
    
                    result = await auditDataAccessor.BatchAddAudit(list.Adapt<List<AuditDao>>()).ConfigureAwait(false);
                    return result;
                }
                catch (Exception ex)
                {
                    loggerHelper.Error(apiActionDescriptorModel.ControllerName + apiActionDescriptorModel.ActionName + "插入审计失败,失败原因:" + ex.ToString());
                    return result;
                }
            }
    
            private List<AuditModel> HandleApiAction(ApiActionDescriptorModel apiActionDescriptorModel, List<AuditRuleModel> auditRuleModels)
            {
                int apiEnum = (int)EnumHelper.GetValue(typeof(HttpMethodEnum), apiActionDescriptorModel.HttpMethod?.ToLower());
    
                var auditRuleModel = auditRuleModels.Where(t => t.ControllerName == apiActionDescriptorModel.ControllerName
                 && t.ActionName == apiActionDescriptorModel.ActionName
                 && t.HttpMethod == apiEnum)?.FirstOrDefault();
    
                List<AuditModel> list = new List<AuditModel>();
                if (auditRuleModel == null) return list;
    
                if (!string.IsNullOrEmpty(auditRuleModel.AuditRuleDescr))
                {
                    var audits = GetAudits(apiActionDescriptorModel, auditRuleModel);
    
                    if (audits != null && audits.Count > 0)
                        list = GetAudits(apiActionDescriptorModel, auditRuleModel, audits);
                }
    
                return list;
            }
    
            private List<AuditModel> GetAudits(ApiActionDescriptorModel apiActionDescriptorModel, AuditRuleModel auditRuleModel, List<string> audits)
            {
                List<AuditModel> auditModels = new List<AuditModel>();
                int responseCode = GetResponseCode(apiActionDescriptorModel?.ResposeBody);
                for (int i = 0; i < audits.Count; i++)
                {
                    AuditModel auditModel = new AuditModel();
                    auditModel.UserName = apiActionDescriptorModel.Operator;
                    auditModel.AddTime = apiActionDescriptorModel.OperaTime;
                    auditModel.Ip = apiActionDescriptorModel.RequestIp.Replace("localhost", "127.0.0.1");
                    auditModel.ResponseCode = responseCode;
                    auditModel.ModelType = auditRuleModel.ModelType;
                    auditModel.Type = EnumHelper.Parse<OperateType>(auditRuleModel.OperateType);
                    auditModel.IncidenceLevel = EnumHelper.Parse<IncidenceLevel>(auditRuleModel.IncidenceLevel);
                    auditModel.Detail = audits[i];
                    auditModel.UserId = apiActionDescriptorModel.UserId;
                    auditModel.UserName = apiActionDescriptorModel.Operator;
    
                    auditModels.Add(auditModel);
                }
                return auditModels;
            }
    
            private List<string> GetAudits(ApiActionDescriptorModel apiActionDescriptorModel, AuditRuleModel auditRuleModel)
            {
                var jsonDics = GetKeyValues(apiActionDescriptorModel.RequestBody);
                var urlDics = GetKeyValues(apiActionDescriptorModel.QueryString);
    
                foreach (var item in urlDics)
                {
                    if (item != null && item.Count > 0)
                    {
                        foreach (var keyValue in item)
                            jsonDics.ForEach(t => t.Add(keyValue.Key, keyValue.Value));
                    }
                }
    
                List<string> audits = new List<string>();
    
                foreach (var item in jsonDics)
                {
                    var ruleStr = auditRuleModel.AuditRuleDescr;
                    string[] rules = RegularHelper.FindByRegexRemoveRegexs(ruleStr, "【\${.*?}】", "[【】\${}]+");
                    if (rules.Length > 0)
                    {
                        for (int i = 0; i < rules.Length; i++)
                        {
                            if (!item.Keys.Contains(rules[i])) continue;
    
                            string value = item[rules[i]];
                            if (rules[i] == auditRuleModel.AssetIdMappingField)
                                value = assetAccountLoader.GetAssetCacheByCode(value).Name;
    
                            ruleStr = ruleStr.Replace("${" + rules[i] + "}", value);
                        }
                    }
    
                    audits.Add(ruleStr);
                }
                return audits;
            }
    
            private List<Dictionary<string, string>> GetKeyValues(string txt)
            {
                List<Dictionary<string, string>> dics = new List<Dictionary<string, string>>();
    
                if (JsonHelper.StringIsJson(txt))
                {
                    string text = RegularHelper.FindFirstByRegex(txt, @"^[.*?]$");
    
                    List<JObject> jObjects = string.IsNullOrEmpty(text)
                        ? new List<JObject>() { JsonConvert.DeserializeObject<JObject>(txt) }
                        : JsonConvert.DeserializeObject<List<JObject>>(txt);
    
                    foreach (var item in jObjects)
                        dics.Add(item.Properties().ToDictionary(x => x.Name, y => y.Value.ToString()));
                }
                else
                {
                    NameValueCollection collection = HttpUtility.ParseQueryString(txt);
                    var dic = new Dictionary<string, string>();
                    foreach (var item in collection.AllKeys)
                        dic.Add(item, collection[item]);
    
                    dics.Add(dic);
                }
                return dics;
            }
    
            private static int GetResponseCode(string resposeBody)
            {
                int responseCode = -1;
                int.TryParse(RegularHelper.FindContentBetweenTwoRegex(resposeBody, "code":", ","), out responseCode);
                return responseCode;
            }
    
            private List<AuditModel> HandleIsJsonActionToAudit(ApiActionDescriptorModel apiActionDescriptorModel, AuditRuleModel auditRuleModel)
            {
                string text = RegularHelper.FindFirstByRegex(apiActionDescriptorModel.RequestBody, @"^[.*?]$");
    
                List<JObject> jObjects = null;
                if (!string.IsNullOrEmpty(text))
                    jObjects = JsonConvert.DeserializeObject<List<JObject>>(apiActionDescriptorModel.RequestBody);
                else
                    jObjects = new List<JObject>() { JsonConvert.DeserializeObject<JObject>(apiActionDescriptorModel.RequestBody) };
    
                string[] rules = RegularHelper.SplitByRegex(auditRuleModel.AuditRuleDescr, "【.*?】");
    
                List<AuditModel> list = null;
    
                for (int i = 0; i < jObjects.Count; i++)
                {
                    list = new List<AuditModel>(){
                        new AuditModel()
                        {
                            UserName=apiActionDescriptorModel.Operator,
                            ModelType=auditRuleModel.ModelType,
                            Type =EnumHelper.Parse<OperateType>(auditRuleModel.OperateType),
                            IncidenceLevel =EnumHelper.Parse<IncidenceLevel>(auditRuleModel.IncidenceLevel),
                            UserId=apiActionDescriptorModel.UserId,
                            Detail = GetAuditDetailByRuleRule(jObjects[i], rules).ToString(),
                            AddTime = apiActionDescriptorModel.OperaTime,
                            Ip = apiActionDescriptorModel.RequestIp.Replace("localhost","127.0.0.1"),
                            ResponseCode=GetResponseCode(apiActionDescriptorModel?.ResposeBody),
                        }
                    };
                }
    
                return list;
            }
    
            private List<AuditModel> HandleNotJsonActionToAduit(ApiActionDescriptorModel apiActionDescriptorModel, AuditRuleModel auditRuleModel)
            {
                string[] rules = RegularHelper.SplitByRegex(auditRuleModel.AuditRuleDescr, "【.*?】");
    
                List<AuditModel> list = null;
                if (rules.Length >= 2)
                {
                    list = new List<AuditModel>(){
                        new AuditModel()
                        {
                             UserName=apiActionDescriptorModel.Operator,
                             ModelType=auditRuleModel.ModelType,
                             Type =EnumHelper.Parse<OperateType>(auditRuleModel.OperateType),
                             IncidenceLevel =EnumHelper.Parse<IncidenceLevel>(auditRuleModel.IncidenceLevel),
                             Detail = GetAuditDetailByRuleRule(apiActionDescriptorModel.RequestBody,rules).ToString(),
                             AddTime = apiActionDescriptorModel.OperaTime,
                             Ip = apiActionDescriptorModel.RequestIp.Replace("localhost","127.0.0.1"),
                             ResponseCode=GetResponseCode(apiActionDescriptorModel?.ResposeBody),
                        }
                    };
                }
                return list;
            }
    
            private StringBuilder GetAuditDetailByRuleRule(string text, string[] rules)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(rules[0]);
    
                for (int i = 1; i < rules.Length; i++)
                    sb.Append(
                        RegularHelper.RegexReplace(
                        rules[i],
                        "【.*?】",
                        "【" + RegularHelper.FindContentBetweenTwoRegex(
                            text, "[\?&]" + RegularHelper.FindContentBetweenTwoRegex(rules[i], @"【${", "}】") + "=", "(&|$)") + "】"
                            ));
    
                return sb;
            }
    
            private StringBuilder GetAuditDetailByRuleRule(JObject jObject, string[] rules)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(rules[0]);
                for (int i = 1; i < rules.Length; i++)
                {
                    try
                    {
                        sb.Append(
                            RegularHelper.RegexReplace(rules[i],
                            "【.*?】",
                        "【" + jObject[RegularHelper.FindContentBetweenTwoRegex(rules[i], @"【${", "}】")].ToString() + "】"
                        ));
                    }
                    catch (Exception ex)
                    {
                        loggerHelper.Error("在" + rules[i] + "查找失败,具体原因:" + ex.ToString());
                        throw;
                    }
                }
    
                return sb;
            }
    

      

     public static string[] FindByRegexRemoveRegexs(string html, string strReg, string remReg)
            {
                string[] strs = FindByRegex(html, strReg);
                List<string> result = new List<string>();
                if (strs.Length > 0)
                {
                    for (int i = 0; i < strs.Length; i++)
                        result.Add(RemoveByRegex(strs[i], remReg));
                }
                return result.ToArray();
            }
    

      

  • 相关阅读:
    Linux一些工具命令
    IDC运维_2
    计算机网络基础_1
    Shell编程基础2
    Shell编程进阶3
    注销无效的vcenter/vcsa
    Dapper中,针对MySQL的Like参数化查询
    墨天轮访谈 | 拓扑岭雷鹏:数据库新思维下的弹性压缩与内存计算
    九问 GBase | 如何看待“科技制裁”?如何助力中国数据库国产化落地?
    墨天轮访谈 | 百度云邱学达:GaiaDB如何解决云上场景的业务需求?
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/14250938.html
Copyright © 2020-2023  润新知