using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Filters;using Microsoft.Extensions.Logging;using System;using System.IO;using System.Linq;using System.Net;using System.Text;namespace Dynamics.WebApi.Filters
{ public class CustomerActionFilter : ActionFilterAttribute { /// <summary> /// /// </summary> private const string key = "enterTime"; /// <summary> /// /// </summary> private readonly ILogger _logger; /// <summary> /// /// </summary> /// <param name="loggerFactory"></param> public CustomerActionFilter(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<CustomerActionFilter>(); } /// <summary> /// 执行前拦截记录请求参数 /// </summary> /// <param name="context"></param> public override void OnActionExecuting(ActionExecutingContext context) { var actionDescriptor = string.Empty; try { #region 记录请求日志 string requestBody = ""; Stream stream = context.HttpContext.Request.Body; long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value; if (stream != null) { stream.Position = 0; byte[] buffer = new byte[contentLen]; stream.Read(buffer, 0, buffer.Length); // 转化为字符串 requestBody = Encoding.UTF8.GetString(buffer); } long enterTime = DateTime.Now.Ticks; context.ActionDescriptor.Properties[key] = enterTime; context.HttpContext.Request.Headers.Append(key, new Microsoft.Extensions.Primitives.StringValues(enterTime.ToString())); //[POST_Request] {requestid} http://dev.localhost/messagr/api/message/send {data} actionDescriptor = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ControllerName + "/" + ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName; var url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString; _logger.LogDebug(string.Format("[{0}_Request] [{1}] {2} {3}\r\n{4}" , actionDescriptor , context.HttpContext.Request.Method , enterTime , url, requestBody)); #endregion#region 请求参数验证
if (!context.ModelState.IsValid) { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; var errors = context.ModelState.Values.Select(s => s.Errors.Select(t => t.ErrorMessage)); context.Result = new JsonResult(errors); } #endregion } catch (Exception e) { _logger.LogError(e.Message + e.StackTrace); } finally { base.OnActionExecuting(context); } } /// <summary> /// 执行后拦截记录返回结果耗时 /// </summary> /// <param name="context"></param> public override void OnActionExecuted(ActionExecutedContext context) { string responseBody = string.Empty; try { long enterTime = 0; var costTime = string.Empty; if (context.HttpContext.Request.Headers.TryGetValue(key, out var request_entertime)) { enterTime = Convert.ToInt64(request_entertime); costTime = new TimeSpan(DateTime.Now.Ticks - enterTime).ToString(); } dynamic result = context.Result.GetType().Name == "EmptyResult" ? new { Value = "无返回结果" } : context.Result as dynamic; if (result != null) { responseBody = Newtonsoft.Json.JsonConvert.SerializeObject(result.Value); } var actionDescriptor = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ControllerName + "/" + ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName; _logger.LogDebug(string.Format("[{0}_Response] {1} CostTime:{2}\r\n{3}" , actionDescriptor , enterTime , costTime , responseBody)); } catch (Exception e) { _logger.LogError(e.Message + e.StackTrace); } finally { base.OnActionExecuted(context); } } }}