WebSecurity.InitializeDatabaseConnection上的键“attachdbfilename”的值无效

时间:2012-10-07 11:53:15

标签: asp.net-mvc-4 connection-string entity-framework-5 localdb simplemembership

尝试使用SimpleMembership初始化数据库连接时收到此错误消息。第一个初始化语句通过,而第二个初始化语句没有。目标是在运行Azure模拟器或部署时使用Azure服务配置中定义的连接字符串。

的Web.config:

<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-**********;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-**********.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>

Azure .cscfg配置文件:

<Setting name="SqlConnectionString" value="Server=Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-********;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-********.mdf" />

SimpleMembershipInitializer:

string connectionStringName = "DefaultConnection";
string connectionString = CloudConfigurationManager.GetSetting("SqlConnectionString");
const string userTableName = "UserProfile";
const string providerName = "System.Data.SqlClient";
const string userIdColumn = "UserId";
const string userNameColumn = "UserName";

// This works fine.
// WebSecurity.InitializeDatabaseConnection(connectionStringName, userTableName, userIdColumn, userNameColumn, autoCreateTables: true);

// This throws exception.
// WebSecurity.InitializeDatabaseConnection(connectionString, providerName, userTableName, userIdColumn, userNameColumn, autoCreateTables: true);

环境:Visual Studio 2012,EntityFramework 5.0和MVC4 RTM,默认的SimpleMembership结构。

完整的堆栈跟踪:

[ArgumentException: Invalid value for key 'attachdbfilename'.]
   System.Data.SqlClient.SqlConnectionString.VerifyLocalHostAndFixup(String& host, Boolean enforceLocalHost, Boolean fixup) +888986
   System.Data.SqlClient.SqlConnectionString..ctor(String connectionString) +5330002
   System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous) +24
   System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions) +167
   System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key) +61
   System.Data.SqlClient.SqlConnection.set_ConnectionString(String value) +66
   WebMatrix.Data.DbProviderFactoryWrapper.CreateConnection(String connectionString) +96
   WebMatrix.Data.<>c__DisplayClass15.<OpenConnectionStringInternal>b__14() +16
   WebMatrix.Data.Database.get_Connection() +19
   WebMatrix.Data.Database.EnsureConnectionOpen() +12
   WebMatrix.Data.<QueryInternal>d__0.MoveNext() +66
   System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +164
   WebMatrix.Data.Database.QuerySingle(String commandText, Object[] args) +103
   WebMatrix.WebData.DatabaseWrapper.QuerySingle(String commandText, Object[] parameters) +14
   WebMatrix.WebData.SimpleMembershipProvider.CheckTableExists(IDatabase db, String tableName) +57
   WebMatrix.WebData.SimpleMembershipProvider.CreateTablesIfNeeded() +49
   WebMatrix.WebData.WebSecurity.InitializeMembershipProvider(SimpleMembershipProvider simpleMembership, DatabaseConnectionInfo connect, String userTableName, String userIdColumn, String userNameColumn, Boolean createTables) +73
   WebMatrix.WebData.WebSecurity.InitializeProviders(DatabaseConnectionInfo connect, String userTableName, String userIdColumn, String userNameColumn, Boolean autoCreateTables) +51
   WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection(String connectionString, String providerName, String userTableName, String userIdColumn, String userNameColumn, Boolean autoCreateTables) +63
   MyProject.Filters.SimpleMembershipInitializer..ctor() in c:\Repos\MyRepo\trunk\Web\MyProject\Filters\InitializeSimpleMembershipAttribute.cs:55

[InvalidOperationException: The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588]
   MyProject.Filters.SimpleMembershipInitializer..ctor() in c:\Repos\MyRepo\trunk\Web\MyProject\Filters\InitializeSimpleMembershipAttribute.cs:59

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
   System.Activator.CreateInstance(Type type) +6
   System.Threading.LazyHelpers`1.ActivatorFactorySelector() +68
   System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +115
   System.Threading.LazyInitializer.EnsureInitialized(T& target, Boolean& initialized, Object& syncLock) +106
   MyProject.Filters.InitializeSimpleMembershipAttribute.OnActionExecuting(ActionExecutingContext filterContext) in c:\Repos\MyRepo\trunk\Web\MyProject\Filters\InitializeSimpleMembershipAttribute.cs:23
   System.Web.Mvc.Async.AsyncControllerActionInvoker.InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func`1 nextInChain) +69
   System.Web.Mvc.Async.<>c__DisplayClass3b.<BeginInvokeActionMethodWithFilters>b__35() +21
   System.Web.Mvc.Async.AsyncControllerActionInvoker.InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func`1 nextInChain) +489
   System.Web.Mvc.Async.<>c__DisplayClass3b.<BeginInvokeActionMethodWithFilters>b__35() +21
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__31(AsyncCallback asyncCallback, Object asyncState) +191
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters, AsyncCallback callback, Object state) +197
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

3 个答案:

答案 0 :(得分:1)

在我看来,您可能会遇到缺少双重逃避(\\v11.0而不是\v11.0),如this post中所述。

答案 1 :(得分:1)

我很惭愧地意识到我的连接字符串中有拼写错误。我从Azure部署配置文件中获取连接字符串,例如:

<Setting name="SqlConnectionString" value="Server=Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-********;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-********.mdf" />

此处包含错字,位于值字符串的开头。它一定是一个版权'n'的错误。

此字符串在Azure配置文件Local.cscfg和Cloud.cscfg中分别用于Azure模拟器和Azure部署,以及在web.config中用于在模拟器外部运行。错字只出现在Local.cscfg文件中,这使我在试图找出它在某些情况下不起作用的原因时非常困惑。此外,由于某种原因,错字很难让我发现。事后来看,我看不出我怎么也没有早点弄清楚这一点。

答案 2 :(得分:0)

我还没有解决方案,但到目前为止,这是我自己的调查和理论:

我看了一下WebSecurity.InitializeDatabaseConnection()的源代码,想想也许我发现了一个bug。它似乎没有设置DatabaseConnectionInfo.Type属性,默认为ConnectionStringName,这可以解释为什么它不喜欢我的连接字符串,因为它会将其解释为连接字符串名称。

WebSecurity类:

public static void InitializeDatabaseConnection(string connectionString, string providerName, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
{
  WebSecurity.InitializeProviders(new DatabaseConnectionInfo()
  {
    ConnectionString = connectionString,
    ProviderName = providerName
  }, userTableName, userIdColumn, userNameColumn, autoCreateTables);
}

DatabaseConnectionInfo类:

public Database Connect()
{
  switch (this.Type)
  {
    case DatabaseConnectionInfo.ConnectionType.ConnectionStringName:
      return Database.Open(this.ConnectionStringName);
    case DatabaseConnectionInfo.ConnectionType.ConnectionString:
      return Database.OpenConnectionString(this.ConnectionString, this.ProviderName);
    default:
      return (Database) null;
  }
}

private enum ConnectionType
{
  ConnectionStringName,
  ConnectionString,
}