1 全局注册 2 ServiceFilter,IOC注册 3 TypeFilter 4 4IFilterFactiory 自定义
ServiceFilter 是利用ioc 容器获取实例
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)) ; var filter = (IFilterMetadata)serviceProvider.GetRequiredService(ServiceType);if (filter is IFilterFactory filterFactory) filter = filterFactory.CreateInstance(serviceProvider) ; return filter;
}
typeFilter 是利用反射CreateInstance 创建对象实例 所以在标记特性的类型,serviceFileter 需要配置映射关系,而typeFilter 不需要的
2 feilter 每次请求都要实例化吗? 答案 是其实会缓存的 如果某个Filter需要实时创建 只有一个办法 就是filterfactory
IsReusable =false 表示 不缓存
3 IHttpContextAccessor 可以注入到attrubute 获取上下文 而且是线程安全的
4 逻辑控制某个控制器 不执行action 标记特性里验证是否有那个Allowanonymous 特性
源码
public void OnAuthorization(AuthorizationFilterContext context) { Console.WriteLine($"This is {nameof(CustomAuthorizationFilterAttribute)} .OnAuthorization"); //throw new Exception("CustomAuthorizationFilter Exception"); if (context.Filters.Any(item => item is IAllowAnonymousFilter))//Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter { return;//匿名特性AllowAnonymousAttribute 会生成Filter } if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))//鉴权授权的Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute { return;//匿名就不检测,直接继续 EndpointMetadata 获取mc 的信息
} string user = context.HttpContext.Request.Query["UserName"]; //var memberValidation = HttpContext.Current.Request.Cookies.Get("CurrentUser");//使用cookie //也可以使用数据库、nosql等介质 //context.HttpContext.GetCurrentUserBySession();//读取用户信息 if (string.IsNullOrEmpty(user))//这里可以根据context.HttpContext.Request.Path判断有没有权限 { if (context.HttpContext.Request.IsAjaxRequest()) { context.Result = new JsonResult(new AjaxResult() { Result = false, StatusCode = 401, Message = "用户未登录", });//断路器 } else { //context.HttpContext.Session.SetString("CurrentUrl", context.HttpContext.Request.Path.Value); context.Result = new RedirectResult("~/Filter/Login"); } } else { Console.WriteLine($"This is {user}访问系统"); //this._logger.LogDebug($"{user} 访问系统"); } }
5 每个fileter 都是可以嵌套的
6 断路器
中断后续流程,走非常规流程,
指定context.Result—就不再继续了---如果有AlwaysRunResultFileter 还会吧AlwaysRunResult 折行。