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对象?当我尝试时,我进入无限循环。