我在MVC 4中遇到自定义成员身份问题当我执行ajax调用以从服务器(控制器)获取部分结果时,我不断收到与上下文生命周期相关的错误,错误总是{“提供者已经已关闭“}或{”已经有一个与此命令关联的打开DataReader,必须先关闭它。“}错误始终位于自定义RoleProvider中。 我将尝试解释当前使用的设置。
我继承了Membership和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的基本服务类,用于创建数据库上下文
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);
}
}
具有ajax的控制器
[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")]
属性添加到处理ajax调用的控制器时开始,我知道这是DbContext的生命周期,用于应用程序的生命周期,控制器服务层被销毁,在每个帖子上重新创建,但我不确定处理这个问题的最佳方法,我之前使用过这个设置,但是使用DI和Windsor并且从未遇到过这个问题,因为IOC正在控制上下文。
最好是创建提供者自己的数据库上下文,还是2个提供者之间的冲突,他们真的需要共享相同的数据库上下文?
任何帮助都会非常感谢
答案 0 :(得分:1)
问题正是你所怀疑的。是因为您正在创建DbContext的单个实例,因此您遇到了连接问题。如果您将它与IOC / DI架构一起使用,那么您将要修复它。另一种选择是手动处理连接。
如何使用Ninject作为IOC容器执行此操作的示例是here 他们需要共享相同的上下文才能解决问题。
答案 1 :(得分:1)
我建议您在每次调用GetRolesForUser
时创建服务图层类:
public override string[] GetRolesForUser(string username)
{
return new AccountService().GetRolesForUser(username);
}