2014-12-18 5 views
0

MVC 응용 프로그램에서 사용자 지정 역할 공급자를 구현했지만 동시 인증 요청이 여러 번 발생하면 다음 오류가 발생합니다. { "연결이 닫히지 않았습니다. 연결의 현재 상태가 연결 중입니다."}사용자 지정 역할 공급자 - { "연결이 닫히지 않았습니다. 연결의 현재 상태가 연결 중입니다."}

내 UserRepository 파일 내에서이 행이 발생합니다. 여기에 다른 스레드에서

var user = _db.Users.SingleOrDefault(u => u.userName == username); 

제안 내 UserRepository 파일의 각 메서드 내에서 별도로 _db 컨텍스트를 인스턴스화해야합니다. 이것은 실제로 문제를 해결하지만 다른 곳에서는 공유 DataContexts에 대해 Session을 사용해야한다고 읽었습니다. 응용 프로그램에는 하나의 DataContext 만 있지만 이것을 사용하는 여러 저장소가 있습니다. 그래서 누군가가이 프로젝트에 오래 머무르기 전에 각 메서드의 시작으로 _db Context를 움직여서 내가 올바른 일을하고 있다는 것을 확인할 수 있다면 정말 대단 할 것입니다.

미리 감사

에 나는 그들이 실행 순서에 따라 아래의 관련 파일을 첨부했습니다.

파일 : Global.asax.cs

void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     if (authCookie != null) 
     { 
      string encTicket = authCookie.Value; 
      if (!String.IsNullOrEmpty(encTicket)) 
      { 
       var ticket = FormsAuthentication.Decrypt(encTicket); 
       var id = new UserIdentity(ticket); 
       var userRoles = Roles.GetRolesForUser(id.Name); //Method in Question 
       var prin = new MyPrincipal(id, userRoles); 
       string userData = ((FormsIdentity)(Context.User.Identity)).Ticket.UserData; 
       var serializer = new JavaScriptSerializer(); 
       prin.User = (User)serializer.Deserialize(userData, typeof(User)); 
       HttpContext.Current.User = prin; 
      } 
     } 
    } 

파일 : CustomRoleProvider.cs

namespace CMS3.Infrastructure 
{ 
public class CustomRoleProvider : RoleProvider 
{ 
    private ILoginRepository _rep; 

    public CustomRoleProvider(ILoginRepository rep) 
    { 
     _rep = rep; 
    } 

    public CustomRoleProvider() 
     : this(new UserRepository()) 
    { } 


    public override string[] GetRolesForUser(string username) 
    { 
     var roles = _rep.GetRolesForUser(username); 
     return roles; 
    } 
} 
} 

파일 : userRepository.cs

namespace CMS3.Ef.Repositories 
{ 
public class UserRepository : ILoginRepository 
{ 
    CMS3Context _db = new CMS3Context(); 
    static PasswordManager pwdManager = new PasswordManager(); 
string[] ILoginRepository.GetRolesForUser(string username) 
    { 
      var user = _db.Users.SingleOrDefault(u => u.userName == username); 
      if (user == null) 
       return new string[] { }; 
      return user.UserRoles == null ? new string[] { } : user.UserRoles.Select(u =>u.Role).Select(u => u.roleName).ToArray(); 

    } 
} 

파일 : ILoginRepository.cs

namespace CMS3.Model.InterfaceRepositories 
{ 
public interface ILoginRepository : IDisposable 
{ 
    tblLogin UserByID(int id); 
    LoginDetails UserByNamePassword(string userName, string password); 
    LoginDetails UserByName(string userName); 
    bool IsUserInRole(string username, string roleName); 
    string[] GetRolesForUser(string username); 
    string[] GetAllRoles(); 
    List<UsersSearchDetails> GetUsers(int count = 0); 
    List<UsersSearchDetails> GetUsers(string searchUser); 
    UsersSearchDetails GetUser(int id); 
    bool AdminChangePassword(int id, string newPassword); 
    bool deActivateUser(int id); 
    List<RoleDetails> getUserRoles(int id); 
    List<RoleDetails> getAvaiableRoles(int id); 
    bool AddRoleToUser(int id, int role); 
    bool RemoveRoleFromUser(int id, int role); 
    bool UpdateLoginStatus(string userName, bool loginFail); 
    string[] SearchUsers(string term); 
} 

} 여기에 다른 스레드에서

답변

0

제안 내 UserRepository 파일의 각 메서드 내에서 별도로 _db 컨텍스트를 인스턴스화해야합니다. [...] 그래서 누군가가이 프로젝트에 오래 머무르기 전에 각 메소드의 시작으로 _db Context를 움직여서 올바른 일을하고 있음을 확인할 수 있다면 정말 대단 할 것입니다.

이는 사용자가해야하는 것과 완전히 반대입니다. 저장소마다 별도의 dbcontext가 있으면 첫 번째 수준 캐시 (ID 맵)의 이점이 손실되고 각 저장소는 자체적으로 데이터를 캐시합니다. 당신이 것 당신의 MVC 응용 프로그램에서, 예를 들어, 공유,

public class UserRepository : ILoginRepository 
{ 
    CMS3Context _db; 

    public UserRepository(CMS3Context db) 
    { 
     this._db = db; 
    } 

    ... 
} 

이 방법, 당신은 컨텍스트를 주입 여부 :

대신 dbcontext의 수명 관리의 외부 방법에 따라 저장소 구현해야한다 일반적으로 http 요청 당 하나의 컨텍스트가 있습니다.

+0

고맙습니다. 그 말이 완벽합니다. –