2014-12-06 1 views
2

ASP.NET MVC5, EF6 & Ninject as Backend, 토큰 기반 인증 (JWT)이있는 프론트 엔드로 AngularJS 사용.마이너 코드 수정 후 "폐기 된 객체에 액세스 할 수 없습니다"

최근에 사용자 이름에 @ 문자를 사용하도록 설정해야했습니다. (아래 참조 Ninject에 등록 코드라고도 함) Startup.cs에서 this answer에 대한 자료는, 우리가 바란대로 이것은 @ 기호와 사용자 이름의 등록을 할 수 있습니다

var userManager = new ApplicationUserManager(new UserStore<IdentityUser>(new SecurityDbContext())); 
var validator = new UserValidator<IdentityUser>(userManager) 
{ 
    AllowOnlyAlphanumericUserNames = false 
}; 
userManager.UserValidator = validator; 
UserManagerFactory =() => userManager; 

UserManagerFactory =() => new ApplicationUserManager(new UserStore<IdentityUser>(new SecurityDbContext())); 

를 교체했다. 그러나, (심지어 "정상적인"사용자 이름과 함께) 응용 프로그램에 로그인, 버그가되었다 :

Cannot access a disposed object. 
Object name: 'ApplicationUserManager'. 

자세한 오류 메시지 : 서버의 시작 후 첫 로그인이 평소와 같이 작동하지만, 이후 로그인은 다음과 같은 예외를 생성합니다 : 위의 변경 코드가 NinjectWebCommon.cs에서 호출 :

 
Source Error: 
Line 18:   public override async Task FindAsync(string userName, string password) 
Line 19:   { 
Line 20:    var result = await base.FindAsync(userName, password); 
Line 21:    if (result == null) 
Line 22:    { 

Source File: 
xyz\Infrastructure\ApplicationUserManager.cs Line: 20 

Stack Trace: 

[ObjectDisposedException: Cannot access a disposed object.Object name: 'ApplicationUserManager'.] Microsoft.AspNet.Identity.UserManager`1.ThrowIfDisposed() +99 Microsoft.AspNet.Identity.d__15.MoveNext() +128 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24 xyz.Infrastructure.d__0.MoveNext() in xzy\Infrastructure\ApplicationUserManager.cs:20 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24 xyz.Infrastructure.d__0.MoveNext() in xyz\Infrastructure\ApplicationOAuthProvider.cs:39 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 Microsoft.Owin.Security.OAuth.d__3a.MoveNext() +862 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24 Microsoft.Owin.Security.OAuth.d__1e.MoveNext() +2335 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 Microsoft.Owin.Security.OAuth.d__0.MoveNext() +1728 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +664 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +22 Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() +33 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +150 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +42 System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +415 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

나는 그렇게 여기, Ninject에 함께 할 수있는 뭔가가 조금 더 많은 배경 같아요

kernel.Bind<IUserService>() 
    .To<UserService>() 
    .WithConstructorArgument("userManager", Startup.UserManagerFactory()); 

답변

3

문제점 : 이것은 오브젝트 수명 오류입니다.

솔루션 : 코드를 다음으로 대체하십시오.

UserManagerFactory =() => 
{ 
    var userManager = new ApplicationUserManager(new UserStore<IdentityUser>(new SecurityDbContext())); 
    var validator = new UserValidator<IdentityUser>(userManager) 
    { 
     AllowOnlyAlphanumericUserNames = false 
    }; 
    userManager.UserValidator = validator; 

    return userManager; 
}; 

설명 :

  • 컨트롤러가 IUserService 필요 Ninject에 앞서가는 새로운 UserService를 구성하려고 할 때마다.
  • UserService(IUserManager userManager) 생성자는 userManager없이 호출 할 수 없으므로 Ninject는 구성된대로 Startup.UserManagerFactory()을 호출합니다.
  • 귀하의 경우 UserManagerFactory은 캡처 된 변수 userManager을 반환하는 람다 식입니다. 이것은 항상 동일한 인스턴스가됩니다.
  • 처음으로이 예상대로 작동합니다. 요청이 처리되면 사용자 관리자 인스턴스에서 Dispose이 호출됩니다.
  • 다음 요청을 처리해야하는 경우 이미 배치 된 인스턴스가 다시 사용됩니다. 이것은 실패합니다.
  • 수정 된 버전도 람다 식이지만 이번에는 매번 새 인스턴스를 만듭니다.
+0

charme처럼 작동하고 뭔가를 배웠습니다 - 감사합니다! –

+0

윈저와 같은 문제를 해결하고 문제도 해결했습니다. – MvcCmsJon

관련 문제