应用特色捕捉十分,至极的合并处理Attribute

阐明:本代码只适用于.NET
MVC.

宣称:本办法及代码只使用与.NET
Web API.

概述: 

  ASP.NET Web API
的好用利用过的都知情,未有复杂的安插文件,1个简练的ApiController加上必要的Action就能干活。可是项目,总有不行发生,本节就来谈谈API的非凡的集合处理和写统一写log逻辑的消除方案。

概述: 

  ASP.NET Web API
的好用利用过的都知情,未有复杂的配备文件,1个简练的ApiController加上需求的Action就能做事。但是项目,总有越发发生,本节就来谈谈API的万分的统一处理和写统1写log逻辑的缓解方案。

先成立2个类继承ActionFilterAttribute这些抽象类以及贯彻IExceptionFilter接口,并贯彻它的方法OnException。

应用特色捕捉十分,至极的合并处理Attribute。先制造类继承ExceptionFilterAttribute类型并复写OnException方法。

问题:

   在ASP.NET Web
API编写时,假诺每一种API都写极度处理逻辑,不但加大了花费工作量,且每种开发职员处理11分重临的数据结构也互不相同,在10分发生意况下,客户端处理卓殊的逻辑就不再通用,也还要加大了对接接口职员的工作量,好的API错误码和错误新闻都以固定格式,并后台应该有相应的老大记录。

问题:

   在ASP.NET Web
API编写时,就算各类API都写非凡处理逻辑,不但加大了支付工作量,且每种开发人士处理格外重回的数据结构也不完全相同,在10分发生景况下,客户端处理万分的逻辑就不再通用,也还要加大了对接接口人士的工作量,好的API错误码和错误消息都以固定格式,并后台应该有对应的丰盛记录。

代码如下:

代码如下:

特其余合并处理的兑现:

一.
先是定义杰出处理Attribute,继承System.Web.Http.Filters.ExceptionAttribute,
重写OnException, 代码如下

澳门葡京备用网址 1澳门葡京备用网址 2

 1   public class ErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
 2     {
 3         private string _msg = string.Empty;
 4 
 5         public ErrorHandleAttribute() { }
 6 
 7         public ErrorHandleAttribute(string msg)
 8         {
 9             this._msg = msg;
10         }
11         public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
12         {
13             base.OnException(actionExecutedContext);
14             // 取得发生异常时的错误讯息
15             //var errorMessage = actionExecutedContext.Exception.Message;
16             // 标记log
17             var logAction = actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<NoErrorHandlerAttribute>();
18             if (logAction.Any())
19             {
20                 actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(System.Net.HttpStatusCode.InternalServerError, new ResultData(ResultType.SystemException, actionExecutedContext.Exception.Message));
21                 return;
22             }
23 
24             var request = HttpContext.Current.Request;
25             var logDetail = new LogDetail
26             {
27                 //获取action名称
28                 ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
29                 //获取Controller 名称
30                 ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName,
31                 Navigator = request.UserAgent,
32                 //获取访问的ip
33                 IP = request.UserHostAddress,
34                 UserHostName = request.UserHostName,
35                 UrlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "",
36                 Browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type,
37                 //获取request提交的参数
38                 Paramaters = GetRequestValues(actionExecutedContext),
39                 //获取response响应的结果
40                 //ExecuteResult = GetResponseValues(actionExecutedContext),  //这句会报错,异常没有处理结果
41                 AttrTitle = this._msg,
42                 ErrorMsg = string.Format("错误信息:{0}, 异常跟踪:{1}", actionExecutedContext.Exception.Message, actionExecutedContext.Exception.StackTrace),
43                 RequestUri = request.Url.AbsoluteUri
44             };
45 
46             // 写log
47             var logRep = ContainerManager.Resolve<ISysLogRepository>();
48             var log = new Log()
49             {
50                 Action = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/" + actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
51                 CreateDate = DateTime.Now,
52                 CreatorLoginName = RISContext.Current.CurrentUserInfo.UserName,
53                 IpAddress = request.UserHostAddress,
54                 Detail = Utility.JsonSerialize<LogDetail>(logDetail)
55             };
56 
57             logRep.Add(log);
58             actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(System.Net.HttpStatusCode.InternalServerError, new ResultData(ResultType.SystemException, actionExecutedContext.Exception.Message));
59         }
60         
61         /// <summary>
62         /// 读取request 的提交内容
63         /// </summary>
64         /// <param name="actionExecutedContext"></param>
65         /// <returns></returns>
66         public string GetRequestValues(HttpActionExecutedContext actionExecutedContext)
67         {
68 
69             Stream stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result;
70             Encoding encoding = Encoding.UTF8;
71             /*
72                 这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
73                 因为你关掉后,后面的管道  或拦截器就没办法读取了
74             */
75             var reader = new StreamReader(stream, encoding);
76             string result = reader.ReadToEnd();
77             /*
78             这里也要注意:   stream.Position = 0;
79             当你读取完之后必须把stream的位置设为开始
80             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
81             */
82             stream.Position = 0;
83             return result;
84         }
85     }

View Code

  1. 接下去定义不供给丰硕处理的Attribute,代码如下:

    1 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    2 public class NoErrorHandlerAttribute : Attribute
    3 {
    4 }

  2. 在HttpConfiguration中登记使用 ErrorHandleAttribute, 注册代码如下:

  config.Filters.Add(new ErrorHandleAttribute(“错误处理”));

  1般在档次的WebApiConfig.cs中注册此属性:

 1  /// <summary>
 2     /// WebApiConfig
 3     /// </summary>
 4     public static class WebApiConfig
 5     {
 6         /// <summary>
 7         /// WebApiConfig Register
 8         /// </summary>
 9         /// <param name="config"></param>
10         public static void Register(HttpConfiguration config)
11         {
12             //config.Filters.Add(new TokenAuthorizeAttribute());
13             config.MessageHandlers.Add(new CrosHandler());
14             config.Filters.Add(new ApiAuthorizeAttribute());
15             config.Filters.Add(new ErrorHandleAttribute("错误处理"));
16             // Web API 路由
17             config.Routes.MapHttpRoute(
18                 name: "DefaultApi",
19                 routeTemplate: "mobileapi/{controller}/{action}/{id}",
20                 defaults: new { controller = "Test", action = "GetTestValue", id = RouteParameter.Optional }
21             );
22         }
23     }

那样就能够了,在各样Action中就无须写try
catch了,不然不执行ErrorHandle中那多少个处理逻辑
四.
假设卓殊规的Controller或然Action不要求纪录和拍卖十分,能够在Controller或许Action上添加[NoErrorHandler],那样就不会执行ErrorHandle中丰盛处理逻辑

上述部分是那些的会晤处理逻辑, 接下来贯彻合并写Log的 Attribute作用

卓殊的联结处理的得以实现:

一.
先是定义11分处理Attribute,继承System.Web.Http.Filters.ExceptionAttribute,
重写OnException, 代码如下

澳门葡京备用网址 3澳门葡京备用网址 4

 1   public class ErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
 2     {
 3         private string _msg = string.Empty;
 4 
 5         public ErrorHandleAttribute() { }
 6 
 7         public ErrorHandleAttribute(string msg)
 8         {
 9             this._msg = msg;
10         }
11         public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
12         {
13             base.OnException(actionExecutedContext);
14             // 取得发生异常时的错误讯息
15             //var errorMessage = actionExecutedContext.Exception.Message;
16             // 标记log
17             var logAction = actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<NoErrorHandlerAttribute>();
18             if (logAction.Any())
19             {
20                 actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(System.Net.HttpStatusCode.InternalServerError, new ResultData(ResultType.SystemException, actionExecutedContext.Exception.Message));
21                 return;
22             }
23 
24             var request = HttpContext.Current.Request;
25             var logDetail = new LogDetail
26             {
27                 //获取action名称
28                 ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
29                 //获取Controller 名称
30                 ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName,
31                 Navigator = request.UserAgent,
32                 //获取访问的ip
33                 IP = request.UserHostAddress,
34                 UserHostName = request.UserHostName,
35                 UrlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "",
36                 Browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type,
37                 //获取request提交的参数
38                 Paramaters = GetRequestValues(actionExecutedContext),
39                 //获取response响应的结果
40                 //ExecuteResult = GetResponseValues(actionExecutedContext),  //这句会报错,异常没有处理结果
41                 AttrTitle = this._msg,
42                 ErrorMsg = string.Format("错误信息:{0}, 异常跟踪:{1}", actionExecutedContext.Exception.Message, actionExecutedContext.Exception.StackTrace),
43                 RequestUri = request.Url.AbsoluteUri
44             };
45 
46             // 写log
47             var logRep = ContainerManager.Resolve<ISysLogRepository>();
48             var log = new Log()
49             {
50                 Action = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/" + actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
51                 CreateDate = DateTime.Now,
52                 CreatorLoginName = RISContext.Current.CurrentUserInfo.UserName,
53                 IpAddress = request.UserHostAddress,
54                 Detail = Utility.JsonSerialize<LogDetail>(logDetail)
55             };
56 
57             logRep.Add(log);
58             actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(System.Net.HttpStatusCode.InternalServerError, new ResultData(ResultType.SystemException, actionExecutedContext.Exception.Message));
59         }
60         
61         /// <summary>
62         /// 读取request 的提交内容
63         /// </summary>
64         /// <param name="actionExecutedContext"></param>
65         /// <returns></returns>
66         public string GetRequestValues(HttpActionExecutedContext actionExecutedContext)
67         {
68 
69             Stream stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result;
70             Encoding encoding = Encoding.UTF8;
71             /*
72                 这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
73                 因为你关掉后,后面的管道  或拦截器就没办法读取了
74             */
75             var reader = new StreamReader(stream, encoding);
76             string result = reader.ReadToEnd();
77             /*
78             这里也要注意:   stream.Position = 0;
79             当你读取完之后必须把stream的位置设为开始
80             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
81             */
82             stream.Position = 0;
83             return result;
84         }
85     }

View Code

  1. 接下去定义不供给越发处理的Attribute,代码如下:

    1 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    2 public class NoErrorHandlerAttribute : Attribute
    3 {
    4 }

  2. 在HttpConfiguration中注册使用 ErrorHandleAttribute, 注册代码如下:

  config.Filters.Add(new ErrorHandleAttribute(“错误处理”));

  1般在类型的WebApiConfig.cs中注册此属性:

 1  /// <summary>
 2     /// WebApiConfig
 3     /// </summary>
 4     public static class WebApiConfig
 5     {
 6         /// <summary>
 7         /// WebApiConfig Register
 8         /// </summary>
 9         /// <param name="config"></param>
10         public static void Register(HttpConfiguration config)
11         {
12             //config.Filters.Add(new TokenAuthorizeAttribute());
13             config.MessageHandlers.Add(new CrosHandler());
14             config.Filters.Add(new ApiAuthorizeAttribute());
15             config.Filters.Add(new ErrorHandleAttribute("错误处理"));
16             // Web API 路由
17             config.Routes.MapHttpRoute(
18                 name: "DefaultApi",
19                 routeTemplate: "mobileapi/{controller}/{action}/{id}",
20                 defaults: new { controller = "Test", action = "GetTestValue", id = RouteParameter.Optional }
21             );
22         }
23     }

那般就能够了,在各类Action中就毫无写try
catch了,不然不执行ErrorHandle中优异处理逻辑
4.
万壹非凡规的Controller也许Action不须求纪录和处理分外,可以在Controller或然Action上添加[NoErrorHandler],那样就不会执行ErrorHandle中万分处理逻辑

上述部分是那3个的会师处理逻辑, 接下来贯彻统壹写Log的 Attribute功效

using FrameWork.Common;
using System.Web;
using System.Web.Mvc;

namespace FrameWork.Web
{
    public class ErrorHandleAttribute : ActionFilterAttribute, IExceptionFilter
    {
        /// <summary>
        /// 异常
        /// </summary>
        public void OnException(ExceptionContext filterContext)
        {
            //获取异常信息,入库保存
            var error = filterContext.Exception;
            var message = error.Message;//错误信息
            var url = HttpContext.Current.Request.RawUrl;//错误发生地址
            var controllerName = filterContext.RouteData.Values["controller"].ToString();
            var actionName = filterContext.RouteData.Values["action"].ToString();
            var exception = filterContext.Exception.ToString();

            Log4NetHelp.Error("出错位置:" + url, filterContext.Exception);
            filterContext.HttpContext.Response.Redirect("/Account/Login");//否则跳转至登陆页
        }
    }
}
using System;using System.IO;using System.Net.Http;using System.Text;using System.Web.Http.Filters;using FrameWork.Common;using FrameWork.Common.Const;namespace FrameWork.Web.Handle{    /// <summary>    /// 处理错误信息    /// </summary>    public class ErrorHandleAttribute : ExceptionFilterAttribute    {        public override void OnException(HttpActionExecutedContext filterContext)        {            // 错误处理            base.OnException(filterContext);            var sb = new StringBuilder();            sb.AppendLine("参数:"+ GetExceptionMessage(filterContext));            sb.AppendLine("异常内容:"+ filterContext.Exception.ToJson;            Log4NetHelp.Error(sb.ToString;            filterContext.Response = GetResponse(sb.ToString;        }        /// <summary>        /// 处理错误信息为方便开发人员阅读的格式,包括接口地址以及参数        /// </summary>        /// <param name="actionExecutedContext">异常内容</param>        private string GetExceptionMessage(HttpActionExecutedContext actionExecutedContext)        {            var session = System.Web.HttpContext.Current.Session;            var request = System.Web.HttpContext.Current.Request;            var guid = Guid.NewGuid().ToString();            var task = actionExecutedContext.ActionContext.Request.Content.ReadAsStreamAsync();            var content = string.Empty;            try            {                var sm = task.Result;                if (sm != null)                {                    sm.Seek(0, SeekOrigin.Begin);                    var len = (int)sm.Length;                    var inputByts = new byte[len];                    sm.Read(inputByts, 0, len);                    sm.Close();                    content = Encoding.UTF8.GetString(inputByts);                    sm.Close();                }            }            catch (Exception e)            {                return e.Message;            }            var sessionId = session == null ? "" : session.SessionID;            var pars = string.Format("error:\r\n id = {3};\r\n sessionId = {0};\r\n url = {1};\r\n contentType = {4};\r\n content = {2};"                , sessionId                , request.RawUrl                , content                , guid                , request.ContentType);            return pars;        }        /// <summary>        /// 处理错误信息后执行的方法        /// </summary>        /// <param name="mes">错误信息</param>        private HttpResponseMessage GetResponse(string mes)        {            return JsonHelper.ToJson(new            {                Info = CommonConst.FailStr,                Message = mes,                Msg = false,                ResultCode = CommonConst.FailCode            });        }    }}

统1写Log的 Attribute功效达成:

 一.
先是定义写Log的Attribute,继承System.Web.Http.Filters.ActionFilterAttribute,重写OnActionExecuting和OnActionExecuted,代码如下:

澳门葡京备用网址 5澳门葡京备用网址 6

  1  public class LogAttribute : ActionFilterAttribute
  2     {
  3         private string _msg = string.Empty;
  4         private string _token = string.Empty;
  5         private string _remark = string.Empty;
  6         public LogAttribute() { }
  7 
  8         public LogAttribute(string msg)
  9         {
 10             this._msg = msg;
 11         }
 12 
 13         //http://www.cnblogs.com/shan333chao/p/5002054.html
 14         private static readonly string key = "enterTime";
 15         private const string UserToken = "token";
 16         public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
 17         {
 18             if (actionContext.Request.Method != HttpMethod.Options)
 19             {
 20                 // 标记log
 21                 var logAction = actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>();
 22                 if (!logAction.Any())
 23                 {
 24                     actionContext.Request.Properties[key] = DateTime.Now.ToBinary();
 25                     this._token = GetToken(actionContext, out this._remark);
 26                 }
 27             }
 28             base.OnActionExecuting(actionContext);
 29         }
 30 
 31         public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
 32         {
 33             if (actionExecutedContext.Request.Method != HttpMethod.Options)
 34             {
 35                 object beginTime = null;
 36                 if (actionExecutedContext.Request.Properties.TryGetValue(key, out beginTime))
 37                 {
 38                     DateTime time = DateTime.FromBinary(Convert.ToInt64(beginTime));
 39                     var request = HttpContext.Current.Request;
 40                     var logDetail = new LogDetail
 41                     {
 42                         //获取action名称
 43                         ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
 44                         //获取Controller 名称
 45                         ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName,
 46                         //获取action开始执行的时间
 47                         EnterTime = time,
 48                         //获取执行action的耗时
 49                         CostTime = (DateTime.Now - time).TotalMilliseconds,
 50                         Navigator = request.UserAgent,
 51                         Token = this._token,
 52                         //获取用户ID
 53                         UId = UserTokenManager.GetUId(this._token),
 54                         //获取访问的ip
 55                         IP = request.UserHostAddress,
 56                         UserHostName = request.UserHostName,
 57                         UrlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "",
 58                         Browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type,
 59                         //获取request提交的参数
 60                         Paramaters = GetRequestValues(actionExecutedContext),
 61                         //获取response响应的结果
 62                         ExecuteResult = GetResponseValues(actionExecutedContext),
 63                         AttrTitle = this._msg,
 64                         Remark = this._remark,
 65                         RequestUri = request.Url.AbsoluteUri
 66                     };
 67 
 68                     // 登录log
 69                     var logRep = ContainerManager.Resolve<ISysLogRepository>();
 70                     var log = new Log()
 71                     {
 72                         Action = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/" + actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
 73                         CreateDate = DateTime.Now,
 74                         CreatorLoginName = RISContext.Current.CurrentUserInfo.UserName,
 75                         IpAddress = request.UserHostAddress,
 76                         Detail = Utility.JsonSerialize<LogDetail>(logDetail)
 77                     };
 78 
 79                     logRep.Add(log);
 80                 }
 81             }
 82 
 83             base.OnActionExecuted(actionExecutedContext);
 84         }
 85 
 86         private string GetToken(System.Web.Http.Controllers.HttpActionContext actionContext, out string msg)
 87         {
 88             Dictionary<string, object> actionArguments = actionContext.ActionArguments;
 89             HttpMethod type = actionContext.Request.Method;
 90             msg = "";
 91             var token = "";
 92             if (type == HttpMethod.Post)
 93             {
 94                 if (actionArguments.ContainsKey(UserToken))
 95                 {
 96                     if (actionArguments[UserToken] != null)
 97                         token = actionArguments[UserToken].ToString();
 98                 }
 99                 else
100                 {
101                     foreach (var value in actionArguments.Values)
102                     {
103                         if (value != null && value.GetType().GetProperty(UserToken) != null)
104                             token = value.GetType().GetProperty(UserToken).GetValue(value, null).ToString();
105                     }
106                 }
107 
108                 if (string.IsNullOrEmpty(token))
109                     msg = "匿名用户";
110             }
111             else if (type == HttpMethod.Get)
112             {
113                 if (!actionArguments.ContainsKey(UserToken))
114                     msg = "匿名用户";
115                 // throw new HttpException(401, "还未登录");
116 
117                 if (actionArguments[UserToken] != null)
118                     token = actionArguments[UserToken].ToString();
119                 else
120                     msg = "匿名用户";
121             }
122             else if (type == HttpMethod.Options)
123             {
124 
125             }
126             else
127             {
128                 throw new HttpException(404, "暂未开放除POST,GET之外的访问方式!");
129             }
130             return token;
131         }
132         /// <summary>
133         /// 读取request 的提交内容
134         /// </summary>
135         /// <param name="actionExecutedContext"></param>
136         /// <returns></returns>
137         public string GetRequestValues(HttpActionExecutedContext actionExecutedContext)
138         {
139 
140             Stream stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result;
141             Encoding encoding = Encoding.UTF8;
142             /*
143                 这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
144                 因为你关掉后,后面的管道  或拦截器就没办法读取了
145             */
146             var reader = new StreamReader(stream, encoding);
147             string result = reader.ReadToEnd();
148             /*
149             这里也要注意:   stream.Position = 0;
150             当你读取完之后必须把stream的位置设为开始
151             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
152             */
153             stream.Position = 0;
154             return result;
155         }
156 
157         /// <summary>
158         /// 读取action返回的result
159         /// </summary>
160         /// <param name="actionExecutedContext"></param>
161         /// <returns></returns>
162         public string GetResponseValues(HttpActionExecutedContext actionExecutedContext)
163         {
164             Stream stream = actionExecutedContext.Response.Content.ReadAsStreamAsync().Result;
165             Encoding encoding = Encoding.UTF8;
166             /*
167             这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
168             因为你关掉后,后面的管道  或拦截器就没办法读取了
169             */
170             var reader = new StreamReader(stream, encoding);
171             string result = reader.ReadToEnd();
172             /*
173             这里也要注意:   stream.Position = 0; 
174             当你读取完之后必须把stream的位置设为开始
175             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
176             */
177             stream.Position = 0;
178             return result;
179         }
180     }

View Code

  1. 接下去定义不须要记录log的Attribute,代码如下:

    1 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    2 public class NoErrorHandlerAttribute : Attribute
    3 {
    4 }

  2. 留神不要在HttpConfiguration中注册使用
    LogAttribute,除非你想拥有的请求都写log,在不须求写log的Action上添加[NoLog],不然只供给在急需记录log的Action添加[Log]就足以做到写log的功力。

此篇到此截止,相对相比简单,欢迎大家商量!

 

合并写Log的 Attribute效率完毕:

 壹.
先是定义写Log的Attribute,继承System.Web.Http.Filters.ActionFilterAttribute,重写OnActionExecuting和OnActionExecuted,代码如下:

澳门葡京备用网址 7澳门葡京备用网址 8

  1  public class LogAttribute : ActionFilterAttribute
  2     {
  3         private string _msg = string.Empty;
  4         private string _token = string.Empty;
  5         private string _remark = string.Empty;
  6         public LogAttribute() { }
  7 
  8         public LogAttribute(string msg)
  9         {
 10             this._msg = msg;
 11         }
 12 
 13         //http://www.cnblogs.com/shan333chao/p/5002054.html
 14         private static readonly string key = "enterTime";
 15         private const string UserToken = "token";
 16         public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
 17         {
 18             if (actionContext.Request.Method != HttpMethod.Options)
 19             {
 20                 // 标记log
 21                 var logAction = actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>();
 22                 if (!logAction.Any())
 23                 {
 24                     actionContext.Request.Properties[key] = DateTime.Now.ToBinary();
 25                     this._token = GetToken(actionContext, out this._remark);
 26                 }
 27             }
 28             base.OnActionExecuting(actionContext);
 29         }
 30 
 31         public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
 32         {
 33             if (actionExecutedContext.Request.Method != HttpMethod.Options)
 34             {
 35                 object beginTime = null;
 36                 if (actionExecutedContext.Request.Properties.TryGetValue(key, out beginTime))
 37                 {
 38                     DateTime time = DateTime.FromBinary(Convert.ToInt64(beginTime));
 39                     var request = HttpContext.Current.Request;
 40                     var logDetail = new LogDetail
 41                     {
 42                         //获取action名称
 43                         ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
 44                         //获取Controller 名称
 45                         ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName,
 46                         //获取action开始执行的时间
 47                         EnterTime = time,
 48                         //获取执行action的耗时
 49                         CostTime = (DateTime.Now - time).TotalMilliseconds,
 50                         Navigator = request.UserAgent,
 51                         Token = this._token,
 52                         //获取用户ID
 53                         UId = UserTokenManager.GetUId(this._token),
 54                         //获取访问的ip
 55                         IP = request.UserHostAddress,
 56                         UserHostName = request.UserHostName,
 57                         UrlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "",
 58                         Browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type,
 59                         //获取request提交的参数
 60                         Paramaters = GetRequestValues(actionExecutedContext),
 61                         //获取response响应的结果
 62                         ExecuteResult = GetResponseValues(actionExecutedContext),
 63                         AttrTitle = this._msg,
 64                         Remark = this._remark,
 65                         RequestUri = request.Url.AbsoluteUri
 66                     };
 67 
 68                     // 登录log
 69                     var logRep = ContainerManager.Resolve<ISysLogRepository>();
 70                     var log = new Log()
 71                     {
 72                         Action = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/" + actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
 73                         CreateDate = DateTime.Now,
 74                         CreatorLoginName = RISContext.Current.CurrentUserInfo.UserName,
 75                         IpAddress = request.UserHostAddress,
 76                         Detail = Utility.JsonSerialize<LogDetail>(logDetail)
 77                     };
 78 
 79                     logRep.Add(log);
 80                 }
 81             }
 82 
 83             base.OnActionExecuted(actionExecutedContext);
 84         }
 85 
 86         private string GetToken(System.Web.Http.Controllers.HttpActionContext actionContext, out string msg)
 87         {
 88             Dictionary<string, object> actionArguments = actionContext.ActionArguments;
 89             HttpMethod type = actionContext.Request.Method;
 90             msg = "";
 91             var token = "";
 92             if (type == HttpMethod.Post)
 93             {
 94                 if (actionArguments.ContainsKey(UserToken))
 95                 {
 96                     if (actionArguments[UserToken] != null)
 97                         token = actionArguments[UserToken].ToString();
 98                 }
 99                 else
100                 {
101                     foreach (var value in actionArguments.Values)
102                     {
103                         if (value != null && value.GetType().GetProperty(UserToken) != null)
104                             token = value.GetType().GetProperty(UserToken).GetValue(value, null).ToString();
105                     }
106                 }
107 
108                 if (string.IsNullOrEmpty(token))
109                     msg = "匿名用户";
110             }
111             else if (type == HttpMethod.Get)
112             {
113                 if (!actionArguments.ContainsKey(UserToken))
114                     msg = "匿名用户";
115                 // throw new HttpException(401, "还未登录");
116 
117                 if (actionArguments[UserToken] != null)
118                     token = actionArguments[UserToken].ToString();
119                 else
120                     msg = "匿名用户";
121             }
122             else if (type == HttpMethod.Options)
123             {
124 
125             }
126             else
127             {
128                 throw new HttpException(404, "暂未开放除POST,GET之外的访问方式!");
129             }
130             return token;
131         }
132         /// <summary>
133         /// 读取request 的提交内容
134         /// </summary>
135         /// <param name="actionExecutedContext"></param>
136         /// <returns></returns>
137         public string GetRequestValues(HttpActionExecutedContext actionExecutedContext)
138         {
139 
140             Stream stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result;
141             Encoding encoding = Encoding.UTF8;
142             /*
143                 这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
144                 因为你关掉后,后面的管道  或拦截器就没办法读取了
145             */
146             var reader = new StreamReader(stream, encoding);
147             string result = reader.ReadToEnd();
148             /*
149             这里也要注意:   stream.Position = 0;
150             当你读取完之后必须把stream的位置设为开始
151             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
152             */
153             stream.Position = 0;
154             return result;
155         }
156 
157         /// <summary>
158         /// 读取action返回的result
159         /// </summary>
160         /// <param name="actionExecutedContext"></param>
161         /// <returns></returns>
162         public string GetResponseValues(HttpActionExecutedContext actionExecutedContext)
163         {
164             Stream stream = actionExecutedContext.Response.Content.ReadAsStreamAsync().Result;
165             Encoding encoding = Encoding.UTF8;
166             /*
167             这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
168             因为你关掉后,后面的管道  或拦截器就没办法读取了
169             */
170             var reader = new StreamReader(stream, encoding);
171             string result = reader.ReadToEnd();
172             /*
173             这里也要注意:   stream.Position = 0; 
174             当你读取完之后必须把stream的位置设为开始
175             因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
176             */
177             stream.Position = 0;
178             return result;
179         }
180     }

View Code

  1. 接下去定义不需求记录log的Attribute,代码如下:

    1 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    2 public class NoErrorHandlerAttribute : Attribute
    3 {
    4 }

  2. 只顾不要在HttpConfiguration中注册使用
    LogAttribute,除非你想拥有的请求都写log,在不须要写log的Action上添加[NoLog],不然只必要在供给记录log的Action添加[Log]就能够做到写log的机能。

此篇到此结束,相对相比较简单,欢迎大家议论!

 

什么运用呢?

何以行使呢?

只必要在必要捕捉万分的控制器加上[ErrorHandle]即可。

只须要在须要捕捉万分的控制器加上[ErrorHandle]即可。

例如:

例如:

    [ErrorHandle]
    public abstract class AdminControllerBase : Controller
    {
          //代码逻辑
    }
    [ErrorHandle]    public abstract class AdminControllerBase : Controller    {          //代码逻辑    }

假使接二连三AdminControllerBase或许隐含[ErrorHandle]澳门葡京备用网址,特色的类和办法出现了错误,都会进行OnException方法,

比方持续AdminControllerBase可能隐含[ErrorHandle]特点的类和办法出现了不当,都会执行OnException方法。

接下来写上团结的十二分处理逻辑即可。

能够在处理卓殊的艺术里面添加本人想要的逻辑处理。

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website