I have a simple filter.
public class IsAdmin : ActionFilterAttribute, IAuthenticationFilter
{
private string _roleName;
IBusinessIdentity _identity;
public IsAdmin(string roleName, IBusinessIdentity identity)
{
this._roleName = roleName;
this._identity = identity;
}
public void OnAuthentication(AuthenticationContext filterContext)
{
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
if (!_identity.Roles.Contains(_roleName))
filterContext.Result = new HttpUnauthorizedResult();
}
}
I am using Ninject. Here is my controller. I'm trying to get the injected service into my ActionFilter in order not to take a dependency on HttpContext
but instead on my IBusinessIdentity
.
IBusinessIdentity
gets injected the HttpContext.User.Identity`. And it does a few database calls and gets the userRoles.
public class HomeController : Controller
{
readonly IBusinessIdentity _identity;
public HomeController(IBusinessIdentity identity)
{
this._identity= identity;
}
[IsAdmin("Admin", _identity)]
public ActionResult Index()
{
return View();
}
}
This does not work and I'm getting a compiler error when I try to put the "identity" in the actionfilter constructor at compile time.
An object reference is required for the non-static field, method, or property
I need this because I'm planning to test various permissions with the identity.
I am thinking some kind of reflection to be done after controllers gets instantiated. I have a very vague idea on how it could be done.
I am using ASP.NET MVC 5 and I don't have the kernel.bindfilter. I can't use older version.
I am well aware of this hack.
Action filter constructor being called repeatedly for single controller
https://github.com/ninject/Ninject.Web.Mvc/wiki/Conditional-bindings-for-filters
How can I accomplish the same maybe effect using Ninject for MVC 5.
EDIT: massive failure
I forgot to include the:
using Ninject.Web.Mvc.FilterBindingSyntax;
Now everything works as explained in the above links.
Now I need to figure out how to inject the "roleName" string in the filter constructor. Although I think just construct a filter for every role. I will post entire code later.
Although your question is different, the answer is exactly the same as this one.
DI friendly attributes should never define any behavior. You need to separate the behavior out into a separate filter that can have its dependencies injected at application startup. This can be done by splitting your action filter attribute into 2 parts.
Don't let Microsoft's marketing of ActionFilterAttribute fool you. That approach is completely hostile to DI.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With