下面是我的情况:

我已经成功地创建的自定义的IIdentity我传递到的GenericPrincipal。当我访问的IIdentity在我的控制器我要投的IIdentity的,以使用自定义属性。例如:

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

因为我需要为几乎每一个动作做到这一点铸造我想在ActionFilterAttribute来包装这个功能。我不能做到这一点在控制器的构造函数,因为上下文尚未初始化。我的想法是有ActionFilterAttribute填充控制器,我可以在每个操作方法使用的私人财产。例如:

public class TestController : Controller
{
    private MyCustomIdentity identity;

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

问:这是可能的,如何?有没有更好的解决办法?我已经折磨我的大脑试图找出如何通过被填充到控制器属性的公共属性和我不能得到它。

有帮助吗?

解决方案

所有你需要做的就是访问一个重载OnActionExecuting()方法,让公众认同的ActionExecutingContext而不是私人所以你actionfilter可以访问它。

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



        base.OnActionExecuting(filterContext);
    }
}

这可以是即使通过使用定制的基本控制器类从容易你的所有控制器的将要继承:

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

和然后:

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

其他提示

您可以使用自定义的模型绑定...

我不记得为什么我用这种方法比@jfar提到(这也是一个不错的选择)基地控制器的方法,但它很适合我,其实我还挺喜欢它,因为我的行为是更多的自我描述通过它们的参数。

MyCustomIdentityModelBinder.cs

public class MyCustomIdentityModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.Model != null)
            throw new InvalidOperationException("Cannot update instances");

        //If the user isn't logged in, return null
        if (!controllerContext.HttpContext.User.Identity.IsAuthenticated)
            return null;

        return controllerContext.HttpContext.User as MyCustomIdentity;
    }
}

在里面你的Global.asax.cs应用启动事件

System.Web.Mvc.ModelBinders.Binders.Add(typeof(MyCustomIdentity), new MyCustomIdentityModelBinder());

然后,每当你有类型MyCustomIdentity的作为动作参数,它会自动使用MyCustomIdentityModelBinder

例如

public class TestController : Controller
{
    public ActionResult Index(MyCustomIdentity identity)
    {
        int userID = identity.UserID;
        ...etc...
    }
}

HTHS,结果 查尔斯

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top