2

I have following global filter code:

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;

        }
    }
}

and i add this filter in the Application_Start event of global.asax:

GlobalFilters.Filters.Add(new UserAuthorizationFilter(), 0);

When I updating Administrator role property e.g IsManageRole from true to false, data was updated to database successfully. Yet in UserAuthorizationFilter property role in administrator object doesn't updated, its still load true value . I have tried calling sessionFactory.Evict(typeof(Role)), session.Clear() but find no luck. Still the data won't load new updated Role property. property was updated if I restart the web application.

How do I solve this? Why nhibernate cache won't be clear and updated with functions above, any suggestion? Please help..

adiga
  • 34,372
  • 9
  • 61
  • 83
Dion Dirza
  • 2,575
  • 2
  • 17
  • 21

1 Answers1

1

It would be interesting here to see implemetnation of the IAdministratorService, how does it cache results of the .GetDetailByName(request) method call.

The point is: ASP.NET MVC Filters are/could be treated as singletons. See: Are ActionFilterAttributes reused across threads? How does that work?:

...In ASP.NET MVC 3, filters are cached more aggressively. Therefore, any custom action filters which improperly store instance state might be broken...

Let's think about them, that they are instantiated once, they live for ever without "re-construction". I.e. no new IoC/DI via constructor.

There could be more ways how to get around that.

I. dirty way would be to call IoCFactory.Container.GetInstance<IAdministratorService>(); in every OnAuthorization(). That should most likely return the fresh new service, with access to fresh data in current session. It should be working ... but: Service Locator is an Anti-Pattern by Mark Seemann

II. see this article by Brad Wilson about providing filters in MVC and mostly the section: Adding Dependency Injection to Filters. In a nutshell, each attribute is enriched with the setter injection, using Unity IoC. see the snippet of the filter provider:

var attributes = base.GetActionAttributes(controllerContext,
                                              actionDescriptor);
foreach (var attribute in attributes) {
  _container.BuildUp(attribute.GetType(), attribute);
}

III. I would go with some shared "application cache" represented by provider pattern. (Despite of the Provider is not a pattern by Mark Seemann).

  • Filter will communicating with some SecurityManager.
  • There will be some singleton SecurityProvider, taking the fresh data from current session(s) and caching them.
  • cache will be cleaned after some reasonable period (minutes for security I'd say)
  • Eventing system on "Security" objects will also trigger the cache.Clear()
  • AOP Mvc Filter will be having access to the up to date security data
Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thanks, this answer really help me fixing my DI for filters using `IFilterProvider`. Also i have made breaking changes how my IoC works, now i'm using `IDependencyResolver`.Also i have store this admin object using session storage.. – Dion Dirza Nov 26 '14 at 04:18
  • Great to see that sir! Enjoy amazing NHibernate ;) – Radim Köhler Nov 26 '14 at 04:32