ASP.NET Identity 出现“创建模型时无法使用上下文”异常

Posted

技术标签:

【中文标题】ASP.NET Identity 出现“创建模型时无法使用上下文”异常【英文标题】:"Context cannot be used while the model is being created" exception with ASP.NET Identity 【发布时间】:2014-02-16 03:06:31 【问题描述】:

为什么当我们调用 AccountApiController.Register() 方法时会发生这种情况?

试图使用上下文是什么? 试图创建上下文的是什么? 我们如何避免这种情况? 我们如何调试这个?

"Message":"发生错误。",

"ExceptionMessage":"模型在运行时不能使用上下文 正在创建。如果使用上下文,可能会抛出此异常 在 OnModelCreating 方法内,或者如果相同的上下文实例是 由多个线程同时访问。请注意,实例成员 DbContext 和相关类的不保证是线程的 安全。”,

"ExceptionType":"System.InvalidOperationException",

“堆栈跟踪”:“

在 System.Web.Http.ApiController.d__1.MoveNext()

--- 从先前抛出异常的位置结束堆栈跟踪

在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)

在 System.Runtime.CompilerServices.TaskAwaiter .HandleNonSuccessAndDebuggerNotification(任务 > 任务)

在 System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()"

【问题讨论】:

请确保您不会对不同的请求使用相同的上下文对象,并确保您在 OnModelCreating 之后发送请求。您可以在方法末尾添加断点。 我们如何确保我们不会对不同的请求使用相同的上下文对象?另外,我不确定添加断点是什么意思,因为我们没有 OnModelCreating 方法。 我了解到 ASP.NET 标识使用工厂模式来为每个请求获取一个 UserManager 实例;这可能是个问题,因为我们的 UserManager 将数据存储在 DbContext 中。嗯。 尝试让你的方法异步,这可能会解决问题 【参考方案1】:

问题是我们没有使用 MS recommends 的工厂模式。

您可以使用 Factory 实现来获取 UserManager 的实例 从 OWIN 上下文中。 ...这是获取实例的推荐方法 UserManager 每个应用程序的请求。

因此,“同一个上下文实例被多个线程同时访问”,因为多个请求和线程共享一个 DbContext。

以下是正确的。它为每次调用 UserManagerFactory 函数创建一个新的 MyDbContext 实例。

UserManagerFactory 
= () => new UserManager<IdentityUser>(new UserStore<IdentityUser>(new MyDbContext()));

以下内容不正确。看起来很相似,但不会为对 UserManagerFactory 的每次调用创建一个新实例。这是我们使用的,所以我们的网站坏了。

var userStore = new UserStore<IdentityUser>(new MyDbContext());                    
var userManager = new UserManager<IdentityUser>(userStore);
UserManagerFactory = () => userManager;

【讨论】:

我应该把它放在我的项目的什么地方?我使用 Unity.Mvc 作为依赖解析器。此外,我使用自己的 UnityOfWork 注入了一个 DbContext,该 DbContext 共享给我的所有存储库。 我有同样的错误信息,这也解决了我的问题。 ????@ShaunLuttin 这里有同样的问题,并通过添加工厂模式修复。谢谢@ShaunLuttin【参考方案2】:

如果connectionString 不正确,也会出现此错误。检查connectionString 是否有效(没有错字等)。

【讨论】:

【参考方案3】:

您是否覆盖 OnModelCreating 方法?如果是这样,您可以分享它或整个上下文类吗?

如果不是,请注意错误信息中的以下内容

或者如果多个线程同时访问同一个上下文实例。请注意,不保证 DbContext 和相关类的实例成员是线程安全的。

如果这没有帮助,您是否使用由 Visual Studio 创建的未更改的 Web API 项目?

【讨论】:

我们不重写 OnModelCreating 方法。此外,我们不使用未更改的 Web API 项目...相反,我们修改了存储 ASP.NET 身份数据和其他网站数据的 DbContext。 我们不确定如何确定同一个上下文实例是否被多个线程同时访问。嗯。【参考方案4】:

TL&DR:如果目标是模型播种,并且您正在使用实体框架,我强烈建议您查看以下链接: https://docs.microsoft.com/en-us/ef/core/modeling/data-seeding

此链接详细说明了如何在迁移过程中直接对您的数据进行 SEED。当您希望在创建 DATABASE 期间而不是在应用程序启动期间播种数据时,这通常很有用。

【讨论】:

【参考方案5】:

如果您从表/视图中获取记录,请确保您对数据库对象有足够的访问权限。

我遇到了同样的问题,我通过执行解决了它

sp_change_users_login [ @Action = ] 'action' [ , [ @UserNamePattern = ] 'user' ] [ , [ @LoginName = ] 'login' ] [ , [ @Password = ] 'password' ] [;]


sp_change_users_login 'update_one' 'dbuser' 'dblogin'

Find more snippet and details

【讨论】:

【参考方案6】:

我在 mysql 的多层架构中使用 EF Code First 并且遇到了相同的异常,并且在 DBContext 类构造中使用以下行:

Database.SetInitializer<EntitiesName>(null);

【讨论】:

【参考方案7】:

我同意 Shaun Luttin 的主要回答,但也,

在我的情况下:部署后我遇到了这个错误,我发现原因是在插入 SSL 证书后使用了 Hsts Preload。取消注释这行解决了重定向,它完全解决了这个错误

 //app.UseHsts(options => options.MaxAge(days: 18 * 7).IncludeSubdomains().Preload());

【讨论】:

以上是关于ASP.NET Identity 出现“创建模型时无法使用上下文”异常的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Identity教程ASP.NET Identity入门

ASP.NET Identity系列教程运用ASP.NET Identity

[ASP.NET MVC] ASP.NET Identity登入技术剖析

ASP.NET Identity系列教程Identity高级技术

ASP.NET MVC Identity 添加角色

ASP.NET Identity系列教程(目录)