public override async Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, System.Threading.CancellationToken cancellationToken)
        {
            //断言错误处理
            if(actionExecutedContext.Exception is AssertException)
            {
                AssertMessage assertMessage = new AssertMessage();
                assertMessage.AssertMessageList = (actionExecutedContext.Exception as AssertException).ExceptionMessageList;

                HttpResponseMessage response = actionExecutedContext.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, assertMessage.ToJSON());
                actionExecutedContext.Response = response;
            }            
            else if(actionExecutedContext.Exception is DisplayableException)
            {
                string displayMessage = (actionExecutedContext.Exception as DisplayableException).Message;

                HttpResponseMessage response = actionExecutedContext.Request.CreateResponse<string>(HttpStatusCode.BadRequest, displayMessage);
                actionExecutedContext.Response = response;
            }
            //EntityFramework错误处理,此错误通常为Database Connect Fail,所以不能Log进数据库里,处理方式为发邮件
            else if (actionExecutedContext.Exception is EntityException)
            {
                Exception ex = actionExecutedContext.Exception;
                string msgSubject = "WebApi Error";
                string exMsg = ex.GetType() + "------" + ex.Message + "\r\n";
                string sourceObj = actionExecutedContext.ActionContext.ControllerContext.Controller.ToString() + "." +
                                   actionExecutedContext.ActionContext.ActionDescriptor.ActionName;

                exMsg += "Error Place ------ " + sourceObj + "\r\n";

                while(ex.InnerException != null)
                {
                    ex = ex.InnerException;
                    exMsg += "InnerException" + "\r\n" + ex.Message + ex.StackTrace + "\r\n";
                }

                await SMTPMailClient.SendAsync(msgSubject, exMsg, "*****@*****.**", "", false);

                HttpResponseMessage response = actionExecutedContext.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "System Error");
                actionExecutedContext.Response = response;
            }
            //其它错误处理则Log进数据库
            else
            {
                //Log的错误信息
                Exception ex = actionExecutedContext.Exception;
                string exMsg = ex.GetType() + "------" + ex.Message;
                string sourceObj = actionExecutedContext.ActionContext.ControllerContext.Controller.ToString() + "." +
                                   actionExecutedContext.ActionContext.ActionDescriptor.ActionName;

                //Email的错误信息
                string emailSubject = "WebApi Error";
                string emailMsg = exMsg;
                emailMsg += "Error Place ------ " + sourceObj + "\r\n";

                while(ex.InnerException != null)
                {
                    ex = ex.InnerException;
                    exMsg += "InnerException:" + ex.Message + ex.StackTrace;
                    emailMsg += "InnerException" + "\r\n" + ex.Message + ex.StackTrace + "\r\n";
                }

                SecurityManager securityManager = new SecurityManager();

                Task<bool> logTask = securityManager.WriteLogAsync(Entity.Models.Enums.LogLevel.ERROR, sourceObj, exMsg);                

                bool isSucceedLog = await logTask;

                //如果Log数据库失败,则改为发邮件。
                if(!isSucceedLog)
                {
                    await SMTPMailClient.SendAsync(emailSubject, exMsg, "*****@*****.**", "", false);
                }                

                HttpResponseMessage response = actionExecutedContext.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "System Error");
                actionExecutedContext.Response = response;
            }
        }
        private async Task<HttpResponseMessage> Excute()
        {
            var actionDescriptor = Request.GetActionDescriptor();
            string controller = actionDescriptor.ControllerDescriptor.ControllerName;
            string action = actionDescriptor.ActionName;

            string sourceObj = String.Format("KoalaBlog.WebApi.Controllers.{0}Controller.{1}", controller, action);

            //async log
            Task logTask = new SecurityManager().WriteLogAsync(Entity.Models.Enums.LogLevel.CRITICAL, sourceObj, "Unauthorized");

            HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
            response.ReasonPhrase = ReasonPhrase;
            response.RequestMessage = Request;

            await logTask;

            return response;
        }
        public async System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> ExecuteAuthorizationFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>> continuation)
        {
            if(actionContext == null)
            {
                throw new ArgumentNullException("actionContext");
            }
            if(continuation == null)
            {
                throw new ArgumentNullException("continuation");
            }

            var controllerDescriptor = actionContext.ActionDescriptor.ControllerDescriptor;
            var actionDescriptor = actionContext.ActionDescriptor;

            var cacheKey = controllerDescriptor.ControllerName + "." + actionDescriptor.ActionName;

            //persistent property
            rolesOrPermissionsName = null;

            if(!cacheDic.ContainsKey(cacheKey))
            {
                var attrs = actionDescriptor.GetCustomAttributes<RequireRolesOrPermissionsAttribute>(false);
                if (attrs.Count == 1)
                {
                    rolesOrPermissionsName = ((RequireRolesOrPermissionsAttribute)attrs[0]).RolesOrPermissionsName;
                }
                else
                {
                    attrs = controllerDescriptor.GetCustomAttributes<RequireRolesOrPermissionsAttribute>(false);
                    if (attrs.Count == 1)
                    {
                        rolesOrPermissionsName = ((RequireRolesOrPermissionsAttribute)attrs[0]).RolesOrPermissionsName;
                    }
                }
                if (rolesOrPermissionsName != null)
                {
                    cacheDic[cacheKey] = rolesOrPermissionsName;
                }
            }
            else
            {
                rolesOrPermissionsName = cacheDic[cacheKey];
            }

            if (rolesOrPermissionsName != null)
            {
                bool isAuthorized = await new SecurityManager().IsUserInRoleAsync("admin", rolesOrPermissionsName);

                if(!isAuthorized)
                {
                    string controller = actionDescriptor.ControllerDescriptor.ControllerName;
                    string action = actionDescriptor.ActionName;

                    string sourceObj = String.Format("KoalaBlog.WebApi.Controllers.{0}Controller.{1}", controller, action);

                    System.Threading.Tasks.Task logTask = new SecurityManager().WriteLogAsync(Entity.Models.Enums.LogLevel.WARNING, sourceObj, "Forbidden");

                    //create forbidden response
                    System.Net.Http.HttpResponseMessage response = new System.Net.Http.HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.Forbidden,
                        RequestMessage = actionContext.Request
                    };

                    await logTask;

                    return response;
                }
            }

            return await continuation();
        }