2017-04-04 74 views
0

我需要添加自定義聲明時,通過執行讀取到數據庫中並添加值(從谷歌外部標誌)的用戶體徵恢復。我正在使用Ninject進行依賴注入,以將控制器注入到我的業務層服務中。在asp.net mvc的GenerateUserIdentityAsync使用Ninject添加自定義的要求

所以我所在的identityModels.cs方法添加索賠:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     // Add custom user claims here 

     string userId = userIdentity.GetUserId(); 

     //var _iUserBLL = (IUserBLL)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IUserBLL)); 
     //UserBO objUser = _iUserBLL.GetById(userId); 

     //userIdentity.AddClaim(new Claim("Value1", objUser.Value1)); 
     //userIdentity.AddClaim(new Claim("Value2", objUser.Value2)); 
     return userIdentity; 
    } 

這裏System.Web.Mvc.DependencyResolver.Current.GetService線失敗,並導致其崩潰。這在其他地方工作,我也試過我用注入控制器像相同的方法:

public class MyController : Controller 
{ 
    private readonly IUserBLL _iUserBLL; 

    public MyController (IUserBLL iUserBLL) 
    { 
     _iUserBLL = iUserBLL; 
    } 
} 

甚至:

[Inject] 
    public IUserBLL _iUserBLL { get; set; } 

但在GenerateUserIdentityAsync方法使用時_iUserBLL爲空。任何想法如何我可以注入我的IUserBLL在這裏進行自定義數據庫調用?

多一點信息 - 如果你不熟悉這種方法,它與個人用戶帳戶Visual Studio項目生成的身份代碼的一部分。

類的全是像這樣:

public class ApplicationUser : IdentityUser 
{ 
    public async Task<ClaimsIdentity> 
     GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     ... 
    } 
} 

於是,我就在這裏構造函數,它不工作:

public class ApplicationUser : IdentityUser 
    { 
     private readonly IUserBLL _iUserBLL; 

     public ApplicationUser (IUserBLL iUserBLL) 
     { 
      _iUserBLL = iUserBLL; 
     } 
... 
} 

的IdentityUser在前期的內部運作聲明提供identity.entityframework類,並從我不能編輯的內部調用,所以我很困惑如何處理這個?您的回覆薩姆

感謝,它把我拉到一個解決方案。這是我結束的代碼。我遇到了靜態的'Create'方法,所以我改用了[Inject]屬性。有沒有辦法改變靜態的'Create'方法在構造函數中使用IUserBLL?下面是我使用的代碼:

在App_Start/IdentityConfig.cs

// Configure the application sign-in manager which is used in this application. 
    public class ApplicationSignInManager : SignInManager<ApplicationUser, string> 
    { 
     [Inject] 
     public IUserBLL _iUserBLL { get; set; } 

     public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 
      : base(userManager, authenticationManager) 
     { 
     } 

     public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) 
     { 

      var userIdentity = user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); 

      UserBO objUser = _iUserBLL.GetById(user.Id); 

      userIdentity.Result.AddClaim(new Claim("Claim1", objUser.Value1)); 
      userIdentity.Result.AddClaim(new Claim("Claim2", objUser.Value2)); 

      return userIdentity; 

     } 

     public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) 
     { 
      return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); 
     } 
    } 

在我NinjectWebCommon.cs我還包括這些行,多餘的我所有的綁定:

private static void RegisterServices(IKernel kernel) 
     { 
kernel.Bind<System.Security.Principal.IPrincipal>().ToMethod(context => HttpContext.Current.User).InRequestScope(); 
      kernel.Bind<ApplicationUserManager>().ToMethod(context => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()).InRequestScope(); 
      kernel.Bind<ApplicationSignInManager>().ToMethod((context) => 
      { 
       var cbase = new HttpContextWrapper(HttpContext.Current); 
       return cbase.GetOwinContext().Get<ApplicationSignInManager>(); 
      }); 
... 
} 
+0

如果該方法被從什麼地方叫在那裏你可以成功地注入有問題的接口,然後將它作爲一個方法參數 – Nkosi

+0

你爲什麼不爲IUserBLL做構造器注入類中包含您的GenerateUserIdentityAsync方法與構造函數中的方法相同? –

+0

乾杯,我在上面添加了一些信息。理想情況下,我想只是有'公共類ApplicationUser:IdentityUser { [進樣] 公共IUserBLL _iUserBLL {獲得;組; }' 但_iUserBLL始終爲空。我在NinjectWebCommon.cs中錯過了什麼,告訴Ninject注入這個? – Bluemoon

回答

0

ApplicationUser是實體對象和這種對象是負責保持數據不這樣做的邏輯。如果您在UserManager而不是ApplicationUser添加自定義的要求它會好很多。試想一下:

public class ApplicationUserManager: UserManager<ApplicationUser> 
{ 
    private readonly IUserBLL _iUserBLL; 

    public ApplicationSignInManager(IUserStore<ApplicationUser> store, 
     IUserBLL iUserBLL) 
     : base(store) 
    { 
     // if you already fully integrated Identity with ninject, 
     // ninject could automatically resolve this for you. 
     _iUserBLL=iUserBLL; 
     // other configurations here 
    } 

    public override async Task<ClaimsIdentity> CreateIdentityAsync(
     ApplicationUser user, 
     string authenticationType)   
    { 
     var userIdentity=await base.CreateIdentityAsync(user, authenticationType); 
     UserBO objUser = _iUserBLL.GetById(userId); 

     userIdentity.AddClaim(new Claim("Value1", objUser.Value1)); 
     userIdentity.AddClaim(new Claim("Value2", objUser.Value2)); 

     return userIdentity; 
    } 
} 
+0

謝謝山姆,這對我很有用,我已經用我最終的代碼更新了帖子。由於靜態創建方法,我必須使用[注入],這似乎沒關係? – Bluemoon

+0

由於'ApplicationSignInManager'不需要在Owin上下文中註冊。你可以通過讓ninject初始化ApplicationSignInManager而不是Owin上下文並從'Startup.Auth.cs'文件中刪除它的註冊來擺脫靜態方法。 –

+0

雖然登錄時更改對IdentityConfig方法起作用,但是它是IdentityModels方法,用於重新生成身份(來自Startup.Auth),所以當發生此情況時我將丟失用戶名。所以我回到了原點,如何注入ApplicationUser方法以在IdentityModels.cs中使用我的IUserBLL,GenerateUserIdentityAsync? – Bluemoon