我有以下全局过滤器代码:
public class UserAuthorizationFilter : FilterAttribute, IAuthorizationFilter
{
private readonly IAdministratorService _administratorService;
public UserAuthorizationFilter()
{
_administratorService = IoCFactory.Container.GetInstance<IAdministratorService>();
}
public void OnAuthorization(AuthorizationContext filterContext)
{
string username = HttpContext.Current.User.Identity.Name;
IRequestMessage<string> request = MessageFactory.BuildRequestFor(username, username);
Administrator administrator = _administratorService.GetDetailByName(request).Data;
filterContext.Controller.ViewBag.Username = username;
filterContext.Controller.ViewBag.IsAdmin = administrator != null;
if (administrator != null)
{
bool isManageRole = administrator.Roles.Any(r => r.IsManageRole);
bool isManageAdministrator = administrator.Roles.Any(r => r.IsManageAdministrator);
bool isManageReviewer = administrator.Roles.Any(r => r.IsManageReviewer);
filterContext.Controller.ViewBag.IsManageRole = isManageRole;
filterContext.Controller.ViewBag.IsManageAdministrator = isManageAdministrator;
filterContext.Controller.ViewBag.IsManageReviewer = isManageReviewer;
}
}
}
我在global.asax的Application_Start事件中添加了这个过滤器:
GlobalFilters.Filters.Add(new UserAuthorizationFilter(), 0);
当我将管理员角色属性(例如IsManageRole)从true
更新为false
时,数据已成功更新到数据库。但是,在UserAuthorizationFilter
管理员对象中的属性角色未更新,其仍然加载true
值。我试过调用sessionFactory.Evict(typeof(Role))
,session.Clear()
,但没有找到运气。数据仍然不会加载新更新的Role属性。如果我重新启动Web应用程序,属性已更新。
我该如何解决这个问题?为什么nhibernate缓存不会被上面的函数清楚和更新,有什么建议吗?请帮忙..
答案 0 :(得分:1)
在这里看一下IAdministratorService
的实现会很有意思,它如何缓存 .GetDetailByName(request)
方法调用的结果。
重点是:ASP.NET MVC过滤器可以被视为单例。请参阅:Are ActionFilterAttributes reused across threads? How does that work?:
...在ASP.NET MVC 3中,过滤器被更积极地缓存。因此,任何不正确地存储实例状态的自定义操作过滤器可能会被破坏......
让我们考虑一下,他们被实例化一次,他们永远活着,没有“重建”。即没有新的IoC / DI通过构造函数。
如何解决这个问题还有更多方法。
我。肮脏的方法是在每个IoCFactory.Container.GetInstance<IAdministratorService>();
中拨打 OnAuthorization()
。这应该最有可能返回新的新服务,并在当前会话中访问新数据。它应该起作用......但是:Mark Seemann的Service Locator is an Anti-Pattern
II。请参阅Brad Wilson关于提供filters in MVC的文章,主要是以下部分:向过滤器添加依赖注入。简而言之,使用Unity IoC,每个属性都使用setter注入进行了丰富。请参阅过滤器提供程序的代码段:
var attributes = base.GetActionAttributes(controllerContext,
actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
III。我会选择一些由提供者模式表示的共享“应用程序缓存”。 (尽管有Mark Seemann的Provider is not a pattern)。
SecurityManager
进行通信。 SecurityProvider
,从当前会话中获取新数据并缓存它们。cache.Clear()