c# - 将 IAuthorizationFilter 与 Ninject 和 EF 一起使用会给出 DbContext has been disposed 错误

标签 c# asp.net-mvc entity-framework ninject

我正在尝试在 IAuthorizationFilter 的实现中使用我的 UnitOfWork,但是在我在几个页面之间导航之后我得到了这个异常:

System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.

FilterConfig.cs

filters.Add(DependencyResolver.Current.GetService(typeof(PermissionFilter)));

NinjectMappings.cs

public class NinjectMappings : NinjectModule
{
    public override void Load()
    {
        Bind<MyContext>().ToSelf().InRequestScope();
        Bind<IUnitOfWork>().To<UnitOfWork>();
    }
}

PermissionFilter.cs

public class PermissionFilter : IAuthorizationFilter
{
    public PermissionFilter(IUnitOfWork unitOfWork)
    {
        // etc...
    }
}

我可以通过以下方式解决这个问题:

// NinjectMappings
Bind<IUnitOfWork>()
    .ToMethod(m => GetUnitOfWork())
    .WhenInjectedExactlyInto(typeof(PermissionFilter));

private IUnitOfWork GetUnitOfWork()
{
    return new UnitOfWork(new MyContext());
}

现在的问题是 GetUnitOfWork 只在应用程序启动时被调用一次。我尝试在 InTransientScopeInRequestScope 之间交替,但无济于事。因此不会检索到数据库的更新,而是我的 UnitOfWork 总是返回相同的数据。

我已经阅读了很多关于 DbContext has been disposed 的问题,但没有一个是在实现 IAuthorizationFilter

解决这个问题的最佳方法是什么?我想避免在过滤器内使用 newusing() 或使用服务定位器模式。

最佳答案

您的问题来自于您的 MyContext 是在请求​​范围内实例化并在请求结束时处理的。

要解决这个问题,请避免 new() , using , 或 ServiceLocator 模式,你可能依赖于专用的 IFilterProvider

public class PermissionFilterProvider : IFilterProvider
{
    private readonly Func<PermissionFilter> _permissionFilterFactory = null;

    public PermissionFilterProvider(Func<PermissionFilter> filterFactory)
    {
        _permissionFilterFactory = filterFactory;
    }

    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = new List<Filter>(); 

        // instantiate PermissionFilter action filter  
        filters.Add(new Filter(_permissionFilterFactory(), FilterScope.Action, 0));
        return filters;
    }
}

您的绑定(bind)将是:

public class NinjectMappings : NinjectModule
{
    public override void Load()
    {
        Bind<MyContext>().ToSelf().InRequestScope();
        Bind<IUnitOfWork>().To<UnitOfWork>();
        Bind<IFilterProvider>().To<PermissionFilterProvider>();
        Bind<PermissionFilter>().ToSelf();
    }
}

请注意,您将需要 Ninject Factory 扩展,例如 Ninject.Extensions.Factory实现Func<PermissionFilter> PermissionFilterProvider中的工厂模式构造函数。

此外,我不确定您的 IUnitOfWork 的范围.它不应该和你的MyContext一样吗? ?

关于c# - 将 IAuthorizationFilter 与 Ninject 和 EF 一起使用会给出 DbContext has been disposed 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35122561/

相关文章:

c# - 生成具有不同 'Content' 的单选按钮

c# - 帮助用户在 EditFor 中输入正确的格式

c# - 在 asp.net mvc 中打开 .aspx 文件作为 cshtml 的部分 View

c# - 将多个模型的一个实例映射到 EF Core 中的一个属性

entity-framework - Entity Framework 代码优先 : Setting up One-To-One foreign key association using Annotations

c# - 具有非重复计数的 LINQ 查询

c# - VS2010 - 如何在第一次编译错误时自动停止编译

c# - 优化 C# 文件 IO

c# - 如何从文件读取到流并显示为文本?

linq - Entity Framework 4 生成的查询正在连接完整的表