标签:except 开始 http else reset contain nbsp 方法 token
学习和使用aspnetcore,必定绕不开注入,不得不说,这对我这种一直使用webform并且上了年纪的码农来说,真心的不轻松。这不,又遇到问题了:
一个企业微信的项目,用户和部门信息使用redis存储,项目中引入IDistributedCache来获取redis中的数据,
startup.cs 中注册redis缓存,NuGet中引入Microsoft.Extensions.Caching.Redis
services.AddDistributedRedisCache((options) => { options.Configuration = "127.0.0.1:6379"; });
使用方法:
public class WeixinUserUtil { private CacheHelper _cacheHelper; public WeixinUserUtil(IDistributedCache cache) { _cacheHelper = new CacheHelper(cache); } public List<GetMemberResult> All() { var result = _cacheHelper.Get<List<GetMemberResult>>("WeixinUsers"); if (result == null) { return Init(); } return result; } public GetMemberResult Get(string id) { return All().Where(d => d.userid == id).FirstOrDefault(); } public void Reset() { Init(); } private List<GetMemberResult> Init() { var token = AccessTokenContainer.TryGetToken(WeixinWorkOptions.CorpId, WeixinWorkOptions.Secret); var result = MailListApi.GetDepartmentMemberInfo(token, 1, 1); if (result.errcode != Senparc.Weixin.ReturnCode_Work.请求成功) { throw new Exception("用户列表接口获取失败"); } else { _cacheHelper.Set<List<GetMemberResult>>("WeixinUsers", result.userlist); return result.userlist; } } }
现在问题来了,有一个自定义的AuthorizationFilter需要调用WeixinUserUtil的Get方法来获取用户信息进行验证,但是实例化WeixinUserUtil需要IDistributedCache参数,这就尴尬了,我们一般都是在Controller的构造函数中实现注入,在Attribute上咋整呢?
俗话说,办法总比问题多,遇到问题解决问题呗,咱有万能的百度不是。具体过程就不提了,最终发现了两个东东,似乎可以解决这个问题,TypeFilter和ServiceFilter。
这两个Filter的理论知识这里就不提了,反正也没看太明白,直接看用法吧。
public class TestTypeFilter : TypeFilterAttribute { public TestTypeFilter() : base(typeof(TestFilterImpl)) { } private class TestFilterImpl : IActionFilter { private ILogger _log; public TestFilterImpl(ILoggerFactory loggerFactory) { _log = loggerFactory.CreateLogger<TestFilterImpl>(); } public void OnActionExecuted(ActionExecutedContext context) { _log.LogDebug("TestTypeFilter执行结束"); } public void OnActionExecuting(ActionExecutingContext context) { _log.LogDebug("开始执行TestTypeFilter"); } } }
首先就是定义一个有具体功能的Filter,比如上面的TestFilterImpl(这个命名是跟网上的实例学的),在这个Filter里引入要注入的对象,完成具体功能。
然后再定义一个TypeFilter,继承TypeFilterAttribute,如上面的TestTypeFilter,在构造函数中,把先前定义的Filter当作参数传入给父类,就是这句:
public TestTypeFilter() : base(typeof(TestFilterImpl)) { }
使用起来很简单,直接在Controller或者Action上添加 [TestTypeFilter] 即可。
接下来是ServiceFilter,还是先代码
public class TestServiceAuthorizeFilter : IAuthorizationFilter,, IFilterMetadata { private ILogger logger; public TestServiceAuthorizeFilter(ILoggerFactory logger) { this.logger = logger.CreateLogger("MyAttribute"); } public void OnAuthorization(AuthorizationFilterContext context) { if (!context.HttpContext.User.HasClaim(c => c.Type == ClaimTypes.Role)) { context.Result = new RedirectResult("/Login"); } } }
其实就是定义一个普通Filter,如上面的TestServiceAuthorizeFilter,但是注意一定要加上 IFilterMetadata,事实上这个接口不需要实现任何功能,就是个标记而已。
但到这里并不算完,使用ServiceFilter必须要在Startup.cs 的ConfigureServices中注册
services.AddScoped<TestServiceAuthorizeFilter>();
现在,可以使用这个Filter了,用法如下:
[ServiceFilter(typeof(TestServiceAuthorizeFilter))]
好了,问题解决,没有总结好像挺奇怪的~
结束,谢谢~
标签:except 开始 http else reset contain nbsp 方法 token
原文地址:https://www.cnblogs.com/diwu0510/p/9749036.html