Asp.net MVC自定义成员资格和角色提供程序上下文生存期问题
我在MVC4中的自定义成员身份方面遇到了问题。当我调用ajax从服务器(控制器)获取部分结果时,我一直收到一个与上下文生存期相关的错误,错误总是{“提供程序已关闭”}或{“已经有一个与此命令关联的打开的DataReader,必须先关闭它。”}错误总是在自定义角色Provider中出现。 我将尝试解释我使用的当前设置 我继承了Membership和RoleProvider,并覆盖了所有类似的方法Asp.net MVC自定义成员资格和角色提供程序上下文生存期问题,asp.net,asp.net-mvc,custom-membershipprovider,Asp.net,Asp.net Mvc,Custom Membershipprovider,我在MVC4中的自定义成员身份方面遇到了问题。当我调用ajax从服务器(控制器)获取部分结果时,我一直收到一个与上下文生存期相关的错误,错误总是{“提供程序已关闭”}或{“已经有一个与此命令关联的打开的DataReader,必须先关闭它。”}错误总是在自定义角色Provider中出现。 我将尝试解释我使用的当前设置 我继承了Membership和RoleProvider,并覆盖了所有类似的方法 public class CustomRoleProvider : RoleProvider {
public class CustomRoleProvider : RoleProvider
{
private IAccountService _accountService;
public CustomRoleProvider()
{
_accountService = new AccountService();
}
public override string[] GetRolesForUser(string username)
{
return _accountService.GetRolesForUser(username);
}
}
成员资格提供程序的实现方式与上面的IAccountService相同。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”)]
属性添加到处理ajax调用的控制器时,问题才开始出现,我知道这是DbContext的生命周期,是应用程序的生命周期,控制器服务层在每篇文章中都会被破坏和重新创建,但我不确定处理这一问题的最佳方法,我以前使用过这种设置,但在DI和Windsor中使用过,并且从来没有出现过这个问题,因为IOC控制着上下文
最好将提供者创建为自己的DB上下文,还是两个提供者之间的冲突确实需要共享相同的DB上下文
任何帮助都会很好,谢谢。问题正是你所怀疑的。这是因为您正在创建DbContext的单个实例,因此存在连接问题。如果您将它与IOC/DI模式一起使用,您将修复它。另一个选项是手动处理连接 下面是一个如何使用Ninject作为IOC容器的示例
他们需要共享相同的上下文才能停止问题 我建议您在每次调用
GetRolesForUser
时创建服务层类:
public override string[] GetRolesForUser(string username)
{
return new AccountService().GetRolesForUser(username);
}
谢谢Joe,很简单,但没有想到:)我们应该在项目中尽早实施IOC。。。我认为上面的答案是最好的解决方案,但我可能会用你的想法快速修复。谢谢大家!@Troublemum,我不确定使用IOC注入您的服务是否足以解决您的问题。您的提供商的GetRolesForUser方法可以从多个线程调用,因此需要线程安全。干杯,正如我所预期的,我实际上可能会使用下面的Joe方法作为解决方案,因为我没有时间在应用atm中实现IOC,但这是目前为止更干净的选择。
public override string[] GetRolesForUser(string username)
{
return new AccountService().GetRolesForUser(username);
}