2014-02-18 2 views
2

У меня проблемы с пользовательским членством в MVC 4 Я продолжаю получать связанную с контекстом ошибку, когда я делаю вызов ajax, чтобы получить частичный результат с сервера (контроллера), ошибка всегда {«Поставщик был закрыт»} или {«Уже есть открытый DataReader, связанный с этой Командой, который должен быть закрыт первым».} ошибка всегда попадает в пользовательский RoleProvider. Я попытаюсь объяснить текущую установку im, использующую.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 выше слой услуг, который имеет дело со всеми учетными записями пользователей & ролей все классы обслуживания уровня реализации базового класса обслуживания под названием ServiceBase, что создает контекст DB

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))); 
    } 

} 

Проблема только начался, когда я добавил атрибут к контроллеру, который обработал вызов Ajax [Authorize(Roles = "Administrator,Supplier")], я знаю, что это время жизни DbContext будучи для жизни приложения и уровня обслуживания контроллеров разрушаются и воссоздали на каждом посту, но я не уверен в лучшем способе справиться с этим, я использовал эту настройку раньше, но с DI и Windsor и никогда не сталкивался с этой проблемой, поскольку МОК контролировал контекст.

Было бы лучше, если бы у провайдеров был свой собственный контекст БД или конфликт между двумя провайдерами, и действительно им нужно разделить один и тот же контекст db?

Любая помощь будет большое спасибо

ответ

1

Проблема в том, что именно вы заподозрить. Это связано с тем, что вы создаете один экземпляр DbContext и, следовательно, у вас проблемы с подключением. Если вы используете его с помощью схемы IOC/DI, вы исправите это. Другой вариант - ручное управление соединениями.

Пример того, как это сделать, используя Ninject в качестве контейнера IOC: here Им нужно разделить один и тот же контекст, чтобы проблема остановилась.

+0

Приветствие, так же, как я ожидал, я на самом деле мог бы использовать метод Джо ниже как работа вокруг сейчас, не имеет время для внедрения IOC в приложение atm, но это более чистый вариант. – Troublesum

1

Я хотел бы предложить вам создать свой класс слоя обслуживания на каждый вызов GetRolesForUser:

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

Спасибо Джо, просто, но не думали об этом :) должно было просто сделать время для реализации МОК ранее в проекте ... Я отметил, что этот ответ был лучшим решением, как я чувствую, но я мог бы просто используйте свою идею для быстрого исправления. Спасибо! – Troublesum

+0

@Troublesum, я не уверен, что использование IOC для ввода вашего сервиса будет достаточно, чтобы решить вашу проблему. Метод GetRolesForUser вашего провайдера может быть вызван из нескольких потоков, поэтому он должен быть потокобезопасным. – Joe