Search code examples
asp.net-mvcasp.net-mvc-2custom-attributesiidentity

Custom IIdentity and passing data from an attribute to a controller


Here's my scenario:

I've successfully created a custom IIdentity that I pass to a GenericPrincipal. When I access that IIdentity in my controller I have to cast the IIdentity in order to use the custom properties. example:

public ActionResult Test()
{
    MyCustomIdentity identity = (MyCustomIdentity)User.Identity;
    int userID = identity.UserID;
    ...etc...
}

Since I need to do this casting for nearly every action I would like to wrap this functionality in an ActionFilterAttribute. I can't do it in the controller's constructor because the context isn't initialized yet. My thought would be to have the ActionFilterAttribute populate a private property on the controller that I can use in each action method. example:

public class TestController : Controller
{
    private MyCustomIdentity identity;

    [CastCustomIdentity]
    public ActionResult()
    {
        int userID = identity.UserID;
        ...etc...
    }
}

Question: Is this possible and how? Is there a better solution? I've racked my brain trying to figure out how to pass public properties that are populated in an attribute to the controller and I can't get it.


Solution

  • All you have to do is access the ActionExecutingContext of an overloaded OnActionExecuting() method and make identity public instead of private so your actionfilter can access it.

    public class CastCustomIdentity : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ((TestController) filterContext.Controller).Identity = (MyCustomIdentity)filterContext.HttpContext.User;
    
    
    
            base.OnActionExecuting(filterContext);
        }
    }
    

    This could be even easier by using a custom base controller class that all of your controllers would inherit from:

    public class MyCustomController
    {
        protected MyCustomIdentity Identity { get{ return (MyCustomIdentity)User.Identity; } }
    }
    

    and then:

    public class TestController : MyCustomController
    {
        public ActionResult()
        {
            int userID = Identity.UserId
            ...etc...
        }
    }