标签: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