2014-02-18 2 views
2

MVC 4의 사용자 지정 멤버십에 문제가 있습니다. 서버 (컨트롤러)에서 부분 결과를 얻으려면 아약스 호출을 수행 할 때 컨텍스트 수명 관련 오류가 계속 발생합니다. 오류는 항상 { "공급자가 닫혔습니다"} 또는 { "먼저 닫아야하는이 명령과 연결된 열려있는 DataReader가 있습니다."} 오류는 항상 사용자 지정 RoleProvider 내에 있습니다. 메신저를 사용하여 현재 설정을 설명하려고합니다.MVC 사용자 지정 멤버 및 역할 공급자 컨텍스트 수명 문제

나는 회원 및 RoleProvier에서 상속 등

public class CustomRoleProvider : RoleProvider 
{ 
     private IAccountService _accountService; 

     public CustomRoleProvider() 
     { 
      _accountService = new AccountService(); 
     } 
     public override string[] GetRolesForUser(string username) 
     { 
      return _accountService.GetRolesForUser(username); 
     } 
} 

멤버 자격 공급자가 IAccountService 위의 모든 사용자 처리하는 서비스 계층입니다 같은 방식으로 구현되는 것처럼 모든 메소드를 오버라이드 (override) 한이 & 역할을 차지한다 모든 서비스 레이어 클래스는 DB 컨텍스트를 생성하는 기본 서비스 클래스라는 ServiceBase를 구현

public class ServiceBase 
{ 
    protected Context Context; 

    protected ServiceBase() : this("Context") {} 

    protected ServiceBase(string dbName) 
    { 
     IDatabaseInitializer<Context> initializer = new DbInitialiser(); 
     Database.SetInitializer(initializer); 
     Context = new Context(dbName); 
    } 
} 

그것을

제작에 아약스가있는 컨트롤러
[Authorize(Roles = "Administrator,Supplier")] 
public class AuctionController : Controller 
{ 
    private IAuctionService _service; 

    public AuctionController() 
    { 
     _service = new AuctionService(); 
    } 
    public AuctionController(IAuctionService service) 
    { 
     _service = service; 
    } 
    [CacheControl(HttpCacheability.NoCache), HttpGet] 
    public ActionResult RefreshAuctionTimes(int auctionId) 
    { 
     return PartialView("_AuctionTimer", BusinessLogic.Map.ConvertAuction(_service.GetAuction (auctionId))); 
    } 

} 

나는 아약스 통화를 처리 컨트롤러에 [Authorize(Roles = "Administrator,Supplier")] 속성을 추가 한 경우에만 시작 문제는,이 파괴하고 다시 작성되는 응용 프로그램의 삶과 컨트롤러 서비스 계층에 대한되는 DbContext의 수명을 알고 모든 게시물에서이 문제를 해결하는 가장 좋은 방법은 확실하지 않지만 DI와 Windsor를 사용하기 전에이 설정을 사용했지만 IOC가 컨텍스트를 제어하는 ​​동안이 문제가 발생하지 않았습니다.

공급자 자체의 DB 컨텍스트를 만드는 것이 가장 좋을지, 아니면 2 가지 공급자 간의 충돌이며 실제로 동일한 db 컨텍스트를 공유해야합니까?

도움이 될 것입니다. 감사합니다.

답변

1

문제는 의심스러운 것입니다. 사실 DbContext의 단일 인스턴스를 생성하므로 연결 문제가 발생하기 때문입니다. IOC/DI 스키마와 함께 사용하는 경우 수정해야합니다. 다른 옵션은 연결을 수동으로 처리하는 것입니다.

Ninject를 IOC 컨테이너로 사용하는 방법의 예는 here 입니다. 문제를 막기 위해 동일한 컨텍스트를 공유해야합니다.

+0

건배, 나는 사실을 가지고 있지 않는 한 지금은 주위의 작품으로 아래 조의 방법을 사용할 수 있습니다 예상대로 app atm으로 IOC를 구현하는 시간이지만 이것은 훨씬 더 깨끗한 옵션입니다. – Troublesum

1
당신이 GetRolesForUser 각 통화 서비스 레이어 클래스를 생성 제안

:

public override string[] GetRolesForUser(string username) 
{ 
    return new AccountService().GetRolesForUser(username); 
} 
+0

Joe, 간단하지만 생각하지 못했습니다 :) 프로젝트 초기에 IOC를 구현할 시간을 만들어야합니다 ... 제가 생각하기에 위의 대답을 가장 좋은 해결책으로 표시했습니다. 빠른 수정을 위해 아이디어를 사용하십시오. 고맙습니다! – Troublesum

+0

@Troublesum, IOC를 사용하여 서비스를 주입하는 것이 문제를 해결하기에 충분할 지 확신하지 못합니다. 공급자의 GetRolesForUser 메서드는 여러 스레드에서 호출 할 수 있으므로 스레드로부터 안전해야합니다. – Joe

관련 문제