巧妙使用ActionFilterAttribute记录API日志转载本文请联系UP技控公众号。背景在开发webapi时,一般需要记录api的输入输出信息,方便后续排查问题;日志以委托的形式记录。使用Func这次我们使用另一种方式,Filter来记录输入输出日志。实现方法1、首先定义进入动作时的OnActionExecuting。publicoverridevoidOnActionExecuting(ActionExecutingContextcontext){base.OnActionExecuting(context);//获取请求的requestbody是后面添加的,如果实际项目中不需要删除longcontentLen=context.HttpContext.Request.ContentLength==null?0:上下文。HttpContext.Request.ContentLength.Value;if(contentLen>0){//读取请求体中的所有内容System.IO.Streamstream=context.HttpContext.Request.Body;if(context.HttpContext.Request.Method="POST"){stream.Position=0;}byte[]buffer=newbyte[contentLen];stream.Read(buffer,0,buffer.Length);//转成字符串RequestBody=System.Text.Encoding.UTF8.GetString(缓冲区);}ActionArguments=Newtonsoft.Json.JsonConvert.SerializeObject(context.ActionArguments);Stopwatch=newStopwatch();Stopwatch.Start();}2.定义Stopwatch并计算该方法的时间消耗。privatestringActionArguments{get;set;}//////请求体中的所有值///privatestringRequestBody{get;set;}privateStopwatchStopwatch{get;set;}3.最后,把OnActionExecuted的信息打印出来。publicoverridevoidOnActionExecuted(ActionExecutedContextcontext){base.OnActionExecuted(context);Stopwatch.Stop();stringurl=context.HttpContext.Request.Host+context.HttpContext.Request.Path+context.HttpContext.Request.QueryString;stringmethod=context.HttpContext.Request.Method;stringcontroller=context.Controller.ToString();stringaction=context.ActionDescriptor.DisplayName;stringtoken="";if(context.HttpContext.Request!=null&&context.HttpContext.Request.Headers!=null&&context.HttpContext.Request.Headers["Authorization"].Count>0){token=context.HttpContext.Request.Headers["Authorization"];}stringqs=ActionArguments;dynamicresult=context?.Result?.GetType()?.Name==”EmptyResult"?new{Value="无返回结果"}:context?.Resultasdynamic;stringres="在返回结果前发生了异常";try{if(result!=null){res=Newtonsoft.Json.JsonConvert.SerializeObject(result.Value);}}catch(System.Exception){res="日志未取得结果,返回的数据无方法序列化";}NLogger.Info($"地址:{url}\n"+$"控制器:{controller}\n"+$"动作:{action}\n"+$"令牌:{token}\n"+$"方法:{method}\n"+$"请求体:{RequestBody}\n"+$"参数:{qs}\n"+$"结果:{res}\n"+$"耗时:{Stopwatch.Elapsed.TotalMilliseconds}毫秒(指controller中相应方法执行的时间));}4.controller调用LogAttribute/////////[Produces("application/json")][LogAttribute][CustomExceptionFilterAttribute]publicclassDefaultController:Controller{}完整代码usingCompanyName.ProjectName.Core;usingMicrosoft.AspNetCore。Mvc.Filters;usingSystem.Diagnostics;namespaceCompanyName.ProjectName.HttpApi.Host.Code{//////Interceptor///publicclassLogAttribute:ActionFilterAttribute{privatestringActionArguments{get;set;}//////请求体中的所有值///privatestringRequestBody{get;set;}privateStopwatchStopwatch{get;set;}///////////publicoverridevoidOnActionExecuting(ActionExecutingContextcontext){base.OnActionExecuting(context);//后面添加获取请求的请求体,如果实际不需要删除项目longcontentLen=上下文。HttpContext.Request.ContentLength==null?0:context.HttpContext.Request.ContentLength.Value;if(contentLen>0){//读取请求体中的所有内容System.IO.Streamstream=context.HttpContext.Request.Body;if(context.HttpContext.Request.Method=="POST"){stream.Position=0;}byte[]buffer=newbyte[contentLen];stream.Read(buffer,0,buffer.Length);//转换为字符串RequestBody=System.Text.Encoding.UTF8.GetString(buffer);}ActionArguments=Newtonsoft.Json.JsonConvert.SerializeObject(context.ActionArguments);Stopwatch=newStopwatch();Stopwatch.Start();}////////////publicoverridevoidOnActionExecuted(ActionExecutedContextcontext){base.OnActionExecuted(context);秒表。Stop();stringurl=context.HttpContext.Request.Host+context.HttpContext.Request.Path+context.HttpContext.Request.QueryString;stringmethod=context.HttpContext.Request.Method;stringcontroller=context.Controller.ToString();stringaction=context.ActionDescriptor.DisplayName;stringtoken="";if(context.HttpContext.Request!=null&&context.HttpContext.Request.Headers!=null&&context.HttpContext.Request.Headers["Authorization"].Count>0){token=context.HttpContext.Request.Headers["Authorization"];}stringqs=ActionArguments;dynamicresult=context?.Result?.GetType()?.Name=="EmptyResult"?new{Value="没有返回结果"}:context?.Resultasdynamic;stringres="返回结果前发生异常";try{if(result!=null){res=Newtonsoft.Json.JsonConvert.SerializeObject(result.Value);}}catch(System.Exception){res="日志未获取结果,返回数据无法序列化";}NLogger.Info($"地址:{url}\n"+$"控制器:{controller}\n"+$"动作:{action}\n"+$"令牌:{token}\n"+$"方法:{method}\n"+$"请求体:{RequestBody}\n"+$"参数:{qs}\n"+$"结果:{res}\n"+$"耗时:{Stopwatch.Elapsed.TotalMilliseconds}毫秒(指控制器执行相应方法的时间)");}}}