MVC自定义成员身份和角色提供者上下文生存期问

时间:2014-02-18 11:41:03

标签: asp.net asp.net-mvc custom-membershipprovider

我在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个提供者之间的冲突,他们真的需要共享相同的数据库上下文?

任何帮助都会非常感谢

2 个答案:

答案 0 :(得分:1)

问题正是你所怀疑的。是因为您正在创建DbContext的单个实例,因此您遇到了连接问题。如果您将它与IOC / DI架构一起使用,那么您将要修复它。另一种选择是手动处理连接。

如何使用Ninject作为IOC容器执行此操作的示例是here 他们需要共享相同的上下文才能解决问题。

答案 1 :(得分:1)

我建议您在每次调用GetRolesForUser时创建服务图层类:

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