自定义IIdentity并将数据从属性传递到控制器

时间:2010-04-06 22:36:42

标签: asp.net-mvc asp.net-mvc-2 custom-attributes iidentity

这是我的情景:

我已经成功创建了一个我传递给GenericPrincipal的自定义IIdentity。当我在我的控制器中访问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...
    }
}

问题:这可能吗?如何?有更好的解决方案吗?我试图弄清楚如何将属性中填充的公共属性传递给控制器​​,我无法得到它。

2 个答案:

答案 0 :(得分:1)

您所要做的就是访问重载的OnActionExecuting()方法的ActionExecutingContext并将身份设为public而不是private,以便您的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...
    }
}

答案 1 :(得分:1)

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

我不记得为什么我使用这个方法而不是基本控制器方法@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,
查尔斯