C# 在ASP.NET MVC 3中注入IPrincipal-我做错了什么?

C# 在ASP.NET MVC 3中注入IPrincipal-我做错了什么?,c#,asp.net-mvc-3,razor,ninject,C#,Asp.net Mvc 3,Razor,Ninject,我有一个自定义身份实现: public class FeedbkIdentity : IIdentity { public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Name { get; set; } public FeedbkIdentity() {

我有一个自定义身份实现:

public class FeedbkIdentity : IIdentity
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string Name { get; set; }

    public FeedbkIdentity() 
    {
        // Empty contructor for deserialization
    }

    public FeedbkIdentity(string name)
    {
        this.Name = name;
    }

    public string AuthenticationType
    {
        get { return "Custom"; }
    }

    public bool IsAuthenticated
    {
        get { return !string.IsNullOrEmpty(this.Name); }
    }
}
和习惯原则

public class FeedbkPrincipal : IPrincipal
{
    public IIdentity Identity { get; private set; }

    public FeedbkPrincipal(FeedbkIdentity customIdentity)
    {
        this.Identity = customIdentity;
    }

    public bool IsInRole(string role)
    {
        return true;
    }
}
在global.asax.cs中,我正在反序列化FormsAuthenticationTicket用户数据并替换

HttpContext.Current.User:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        FeedbkIdentity identity = serializer.Deserialize<FeedbkIdentity>(authTicket.UserData);

        FeedbkPrincipal newUser = new FeedbkPrincipal(identity);
        HttpContext.Current.User = newUser;
    }
}
internal class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IUserRepository>().To<EFUserRepository>();
        Bind<IPrincipal>().ToMethod(ctx => ctx.Kernel.Get<RequestContext>().HttpContext.User).InRequestScope();
    }
}
我已经在使用Ninject为成员资格提供程序注入自定义用户存储库,并且我一直在尝试将IPrincipal绑定到HttpContext.Current.User:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        FeedbkIdentity identity = serializer.Deserialize<FeedbkIdentity>(authTicket.UserData);

        FeedbkPrincipal newUser = new FeedbkPrincipal(identity);
        HttpContext.Current.User = newUser;
    }
}
internal class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IUserRepository>().To<EFUserRepository>();
        Bind<IPrincipal>().ToMethod(ctx => ctx.Kernel.Get<RequestContext>().HttpContext.User).InRequestScope();
    }
}
内部类NinjectBindings:NinjectModule
{
公共覆盖无效负载()
{
绑定()到();
Bind().ToMethod(ctx=>ctx.Kernel.Get().HttpContext.User).InRequestScope();
}
}
但它不起作用

我所要做的就是能够访问我的自定义身份属性,如下所示:
@User.Identity.FirstName

我怎样才能做到这一点

编辑

我希望通过将IPrincipal绑定到HttpContext.Current.User(如此处所示):我将能够在我的应用程序中访问
@User.Identity.FirstName


如果情况并非如此,则如链接问题所示,将IPrincipal绑定到HttpContext.Current.User的目的是什么?

我建议您创建自己的基本WebViewPage。看

然后在里面你可以做什么

public FeedbkPrincipal FeedbkPrincipal
{
    get
    {
        return User as FeedbkPrincipal;
    }
}

public FeedbkIdentity FeedbkIdentity
{
     get
     {
         return FeedbkPrincipal.Identity as FeedbkIdentity;
     }
}
public MyClassConstructor(IPrincipal principal) { // }
那就是

@FeedbkIdentity.FirstName
在视野之内

如链接问题所示,将IPrincipal绑定到HttpContext.Current.User的目的是什么

依赖项注入允许您在运行时选择组件。在给出的示例中,您可以

public FeedbkPrincipal FeedbkPrincipal
{
    get
    {
        return User as FeedbkPrincipal;
    }
}

public FeedbkIdentity FeedbkIdentity
{
     get
     {
         return FeedbkPrincipal.Identity as FeedbkIdentity;
     }
}
public MyClassConstructor(IPrincipal principal) { // }

IPrincipal将自动绑定到用户。注意,这将不允许您访问特定的
FeedbkPrincipal
属性,因为即使在运行时它将成为
FeedbkPrincipal
类型,您的类也不知道这一点。依赖项注入不是解决当前问题的方法,因为您确实需要一种访问具体类的方法。

假设
HttpContext.User
设置正确,您可以创建一个全局筛选器,用
FeedbkIdentity
自动填充
ViewBag

例如

创造它

public class FeedbkPrincipalIntoViewBagAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var principal = filterContext.HttpContext.User as FeedbkPrincipal;
        if (principal != null)
        {
            filterContext.Controller.ViewBag.Identity = principal.Identity as FeedbkIdentity;
        }
    }
}
登记

protected void Application_Start()
{
    GlobalFilters.Filters.Add(new FeedbkPrincipalIntoViewBagAttribute());
}
使用它

@ViewBag.Identity.FirstName

定义“不起作用”。什么不起作用?它有什么作用?这和你期望的有什么不同?有错误吗?你需要提供更多的信息。如果最终用户来找你,只是说“它不工作”,你会有什么反应?注意每个人都说“假设…”这是因为你没有告诉我们问题出在哪里。我编辑了这篇文章,但在编辑的上面我提到了我想做什么。我希望能够在Razor视图中使用@User.Identity.FirstName(来自我的自定义IIdentity)。您必须将其强制转换为自定义IIdentity类型。用户被输入到基本界面,所以需要一个cast来获取自定义内容。@MystereMan我理解。但是如果是这样的话,为什么会有人想将IPrincipal绑定到链接问题中的HttpContext.Current.User?有些人这样做是为了测试,但MVC并不需要,因为MVC已经使用interefaces了。至少在我看来,我看不出注射IPrincipal的好理由。然而,如果你真的想。。您可以确保您的自定义IPricipal有自己的接口(IFeedbkPrincipal),然后注入该接口。非常感谢。这将允许我在视图中使用标识类。如果我想在控制器中也使用它们,我可以创建一个基本控制器,并使所有控制器继承类型,如图所示:。如果在控制器级别实现,我是否能够访问视图中的这些自定义属性?在自定义WebViewPage中,您可以拥有将控制器强制转换为基本类型的属性。然后,使用第二个属性MyBaseController.MyUser获取自定义用户属性。这似乎不起作用。对于初学者,我必须为WebViewPage和WebViewPage提供两个单独的实现。然后在我实现代码之后,它仍然无法在视图中识别@FeedbkPrincipal。对于WebViewPage,您可以使用公共抽象类WebViewPage:WebViewPage{},然后将所有逻辑放入WebViewPage中。如果您在配置文件中正确地实现了它,它应该可以工作。如果intellisense没有接收到它,请尝试关闭并重新打开visual Studio。谢谢。成功了。是否无法覆盖视图中的@User对象?当我尝试时,我进入无限循环。