【问题标题】:Asp.Net Identity fails to connect to the database even when EF can successfully connect即使 EF 可以成功连接,Asp.Net Identity 也无法连接到数据库
【发布时间】:2017-06-10 14:29:30
【问题描述】:

控制台应用程序中的一个非常奇怪的问题。 EntityFramework 可以成功连接而不会出现问题,但 ASP.NET Identity v2 失败并出现 SqlException。这是我的代码:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;

namespace TestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // DbContext ctx = new DbContext("DefaultConnectionString");
            // ctx.Database.Connection.Open();



            var username = "mrclan";
            var password = "ap4595821";

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

            var creationResult = userManager.Create(new IdentityUser(username), password);
            Console.WriteLine(creationResult.Succeeded);
        }
    }
}

前 2 行注释用于测试连接字符串,它成功打开了与数据库的连接。

但Identity API无法这样做,在这一行抛出SqlException异常:

var creationResult = userManager.Create(new IdentityUser(username), password);

异常消息是:


在建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供者:SQL 网络接口,错误:50 - 发生本地数据库运行时错误。指定的 LocalDB 实例不存在。


app.config 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnectionString" connectionString="Server=DP-FJ;Database=testDb;user id=sa;password=sa;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v13.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

而安装的Nuget包只有这3个:

如果有帮助的话,完整的堆栈跟踪如下所示:


System.Data.SqlClient.SqlException occurred
  HResult=0x80131904
  Message=A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. The specified LocalDB instance does not exist.
)
  Source=.Net SqlClient Data Provider
  StackTrace:
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.<Open>b__36(DbConnection t, DbConnectionInterceptionContext c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext)
   at System.Data.Entity.SqlServer.SqlProviderServices.<>c__DisplayClass33.<UsingConnection>b__32()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
   at System.Data.Entity.SqlServer.SqlProviderServices.UsingConnection(DbConnection sqlConnection, Action`1 act)
   at System.Data.Entity.SqlServer.SqlProviderServices.UsingMasterConnection(DbConnection sqlConnection, Action`1 act)
   at System.Data.Entity.SqlServer.SqlProviderServices.CreateDatabaseFromScript(Nullable`1 commandTimeout, DbConnection sqlConnection, String createDatabaseScript)
   at System.Data.Entity.SqlServer.SqlProviderServices.DbCreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
   at System.Data.Entity.Core.Objects.ObjectContext.CreateDatabase()
   at System.Data.Entity.Migrations.Utilities.DatabaseCreator.Create(DbConnection connection)
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func`3 createMigrator, ObjectContext objectContext)
   at System.Data.Entity.Internal.InternalContext.CreateDatabase(ObjectContext objectContext, DatabaseExistenceState existenceState)
   at System.Data.Entity.Database.Create(DatabaseExistenceState existenceState)
   at System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context)
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf`1.<CreateInitializationAction>b__e()
   at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
   at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
   at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
   at System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)
   at System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate)
   at Microsoft.AspNet.Identity.EntityFramework.UserStore`6.<GetUserAggregateAsync>d__68.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.UserValidator`2.<ValidateUserName>d__4.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.UserValidator`2.<ValidateAsync>d__0.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.UserManager`2.<CreateAsync>d__0.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.UserManager`2.<CreateAsync>d__d.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
   at Microsoft.AspNet.Identity.UserManagerExtensions.Create[TUser,TKey](UserManager`2 manager, TUser user, String password)
   at AspIdentityPracticeConsole.Program.Main(String[] args) in C:\test\Program.cs:line 27

谢谢。

【问题讨论】:

  • 显然它尝试使用LocalDB(由defaultConnectionFactory部分配置)。一种解决方法是使用new UserStore&lt;IdentityUser&gt;(new YourDbContext("DefaultConnectionString")) 构造函数。
  • 谢谢。这就是答案。将 defaultConnectionFactory 更改为 MSSQLServer 也可以。我尝试使用 localDb 连接字符串开始,但它也不起作用。我的本地 localDb 安装可能有问题。你能发表你的评论作为答案吗?
  • 不客气,很高兴它有帮助:) 但是,我的评论只是一个提示,解决方案实际上取决于你的 DbContext 无参数构造函数的作用,所以我建议你发布一个自我回答描述你是如何解决的,我很乐意为它投票。

标签: .net entity-framework asp.net-identity console-application


【解决方案1】:

虽然很尴尬,但主要问题是 app.config 中的连接字符串名称。 EF 以及 ASP.NET 标识使用的默认连接字符串是 DefaultConnection,而不是 DefaultConnectionString。浪费了一整天的时间来弄清楚:(

但在调试时,我了解到 EF 的几个默认设置,因此还有其他几种解决错误的方法。以下是那些:

  1. 正如@IvanStoev 在 cmets 中提到的,一种解决方案是将DbContext 显式传递给UserStore 的构造函数,而不是依赖默认值。

  2. 将默认连接工厂更改为 SqlServer,而不是 LocalDbConnectionFactory。我们可以通过更改配置文件中的entityframework 节点来做到这一点:

    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="Data Source=.; Integrated Security=True; MultipleActiveResultSets=True" />
      </parameters>
    </defaultConnectionFactory>**
    

    另外一个值得注意的点是,参数值对于SqlConnectionFactory来说是一个完整的连接字符串,如果在value参数值中没有指定InitialCatalog(如上),则默认为@987654326 @,这意味着对于上述情况,EF使用的完整连接字符串是:

    Data Source=.\SQLEXPRESS;Initial Catalog=DefaultConnection;Integrated Security=True;MultipleActiveResultSets=True
    
  3. 自 2016 年以来 LocalDb 的默认别名是 MSSQLLOCALDB。没有了,v 前缀,如 v13.0v11.0

【讨论】:

    猜你喜欢
    • 2011-06-15
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    相关资源
    最近更新 更多