0

这是我的场景:

我已成功创建了一个自定义 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...
    }
}

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

4

2 回答 2

1

您所要做的就是访问重载的 OnActionExecuting() 方法的 ActionExecutingContext 并将身份设为公共而不是私有,以便您的操作过滤器可以访问它。

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...
    }
}
于 2010-04-07T03:20:08.170 回答
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...
    }
}

HTH,
查尔斯

于 2010-04-07T04:55:33.480 回答