好久沒有寫博客了 今天就來聊聊asp.net webapi的過濾器們
過濾器主要有這么幾種
AuthorizationFilterAttribute 權限驗證
ActionFilterAttribute 日志 參數驗證等
ExceptionFilterAttribute 異常處理捕獲
我是如何使用這些過濾器的,最近在做項目中,這幾種過濾器我都使用了,實現當別人調用接口的時候,首先驗證權限,這個驗證信息可以從Head里取也可以從Body里取,然后就是驗證參數的有效性,參數需要后台驗證,在實體里我都是定義了驗證特性,攔截器正好根據這些特性統一做后台驗證,所以我的后台數據驗證統一在這一步就做完了,如果不符合直接拋出給客戶端,然后還可以寫日志,最后是異常的捕獲,異常攔截器統一捕獲異常,我在其它層就不要額外的做異常處理(事務方法除外,事務需要捕獲異常回滾)
這些過濾器 作為全局過濾器直接配置好 不用每個api controller都去聲明特性
/// <summary> /// 接口的權限驗證 /// Token身份驗證,只有合法的用戶才可以訪問 否則會轉向到登錄頁面或者無權限提示頁面 /// </summary> public class AuthGlobalAttribute : AuthorizationFilterAttribute { public string Roles { get; set; } public string Users { get; set; } public override void OnAuthorization(HttpActionContext actionContext) { if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()) { return; } string controllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = actionContext.ActionDescriptor.ActionName; HttpContextBase context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];//獲取傳統context HttpRequestBase request = context.Request;//定義傳統request對象 if (request["Token"] == null && actionContext.Request.Headers.Authorization == null) { Result result = new Result { Flag = false, Message = "缺少Token身份信息", Code="203" }; HttpResponseMessage httpResponseMessage = new HttpResponseMessage(); httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"); httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; actionContext.Response = httpResponseMessage; return; } //參數帶有Token string token = request["Token"]; token = (token ?? actionContext.Request.Headers.Authorization.Parameter); //根據Token獲取當前用戶上下文 if (UserCache.Cache.Get(token) != null) { HttpContext.Current.Items["User"] = UserCache.Cache.Get(token); //獲取用戶上下文后 根據Roles屬性比對過濾器角色 如果沒有權限向外面拋401 } else { Result result = UserBLL.GetUserByToken(token); HttpResponseMessage httpResponseMessage = new HttpResponseMessage(); httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"); httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; actionContext.Response = httpResponseMessage; //actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, new HttpError("您無權限訪問")); return; } base.OnAuthorization(actionContext); } }
/// <summary> /// 全局參數驗證實體 /// </summary> public class ValidateGlobalAttribute : ActionFilterAttribute { /// <summary> /// 所有實體參數接口 全局驗證 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(HttpActionContext filterContext) { if (!filterContext.ModelState.IsValid) { ValidateResults vresult = new ValidateResults(); foreach (string key in filterContext.ModelState.Keys) { if (filterContext.ModelState[key].Errors.Count > 0) { vresult.ErrorResults.Add(new ValidateResult { IsValid = false, MemberName = key, ErrorMessage = filterContext.ModelState[key].Errors[0].ErrorMessage }); } } Result<ValidateResults> result = new Result<ValidateResults> { Flag = false, Message = "數據驗證失敗", ResultObj = vresult,Code="208" }; HttpResponseMessage httpResponseMessage = new HttpResponseMessage(); httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"); httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; filterContext.Response = httpResponseMessage; return; // throw new HttpResponseException(oHttpResponseMessage); } base.OnActionExecuting(filterContext); } }
/// <summary> /// 異常全局處理 /// </summary> public class ExceptionGlobalAtrribute : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext filterContext) { if (filterContext.Exception != null) { string controllerName = filterContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = filterContext.ActionContext.ActionDescriptor.ActionName; HttpContextBase context = (HttpContextBase)filterContext.Request.Properties["MS_HttpContext"];//獲取傳統context HttpRequestBase request = context.Request;//定義傳統request對象 string token = string.Empty; if (request["Token"] != null || filterContext.Request.Headers.Authorization != null) { token = request["Token"]; token = (token ?? filterContext.Request.Headers.Authorization.Parameter); } //獲取當前用戶上下文 UserContext user = UserCache.Cache.Get(token); string description = filterContext.Exception.Message.ToString(); //int autokey = DaoPack.Sys_UserLogDao.GetMax<int>(m => m.AutoKey) + 1; Sys_UserLog log = new Sys_UserLog { //AutoKey = autokey, ActionName = controllerName + "/" + actionName, Description = description, UserID = user == null ? null : (int?)user.UserID, UserName = user == null ? null : user.UserName, Url = request.RawUrl, ClientIP=SysService.GetHostAddress() }; DaoPack.Sys_UserLogDao.Insert(log); } HttpResponseMessage httpResponseMessage = new HttpResponseMessage(); Result result = new Result { Flag = false, Message = "接口異常",Code="400" }; httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"); httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; filterContext.Response = httpResponseMessage; return; //throw new HttpResponseException(oHttpResponseMessage); // base.OnException(filterContext); } }