I'm trying to write an attribute class that can be used on all my "admin" actions which then effectively applies all relevant action/auth filters to that action. For instance, I always apply the AuthoriseAttribute
and a custom AdminLayoutAttribute
, so my intention is to just have an AdminAttribute
which somehow implies both the above. That way I can make changes to the entire Admin section in one handy place.
However I don't see how I can do this. Can any one point me in the right direction?
Much appreciated.
You could consider moving them from the actions to a controller class or a base controller class for the Admin actions. That way you would just set both the Authorize
and AdminLayout
attributes in the controller class instead of each individual action method.
[Authorize]
[AdminLayout]
public AdminController: Controller
{
//action methods
}
Having an attribute combining the authorization and some custom layout logic could be seen as a break of the Single Responsibility Principle, but if you have no other choice then you could try these approaches:
If you want to replace your existing AdminLayoutAttribute
by a new AdminAttribute
, you could then create the AdminAttribute
so it inherits from the standard AuthorizeAttribute
and also implements IActionFilter\IResultFilter as in your custom AdminLayoutAttribute.
public class AdminLayoutAttribute: AuthorizeAttribute, IActionFilter, IResultFilter
{
//Logic as in existing AdminLayoutAttribute to be replaced
}
Otherwise if you want to keep your existing AdminLayoutAttribute
and add a new AdminAttribute
that combines it with the AuthorizeAttribute
, you could then inherit from your custom attribute and implement IAuthorizationFilter by calling an internal instance of type AuthorizationFilter
public class AdminLayoutAttribute: AdminLayoutAttribute, IAuthorizationFilter
{
//Implement IAuthorizationFilter by delegating to an internal AuthorizeFilter instance
private _authorizeFilter = new AuthorizeAttribute();
public override object TypeId
{
//override from base Attribute class as in AuthorizeAttribute class
get { return _authorizeFilter.TypeId ; }
}
public string Roles
{
get { return _authorizeFilter.Roles; }
set { _authorizeFilter.Roles = value; }
}
public string Users
{
get { return _authorizeFilter.Users; }
set { _authorizeFilter.Users = value; }
}
public void OnAuthorization(AuthorizationContext filterContext)
{
_authorizeFilter.OnAuthorization(filterContext);
}
}
The key in both options is to not having the new AdminAttribute class inheriting from 2 concrete classes, as multiple inheritance is not supported by C#.