1

I get this error message when trying to initialize my database connection using SimpleMembership. The first initialize statement goes through, while the second does not. The goal is to use connection strings defined in the Azure service configuration when running Azure emulator or when deployed.

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 configuration files:

<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);

Environment: Visual Studio 2012, EntityFramework 5.0 and MVC4 RTM with default SimpleMembership structure.

Full stacktrace:

[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
angularsen
  • 8,160
  • 1
  • 69
  • 83

3 Answers3

1

It seems to me you might be suffering from the lack of double-escaping (do \\v11.0 instead of \v11.0), as discussed in this post.

Community
  • 1
  • 1
Krzysztof Kozielczyk
  • 5,887
  • 37
  • 28
  • I see that my question was not accurate, I did not create the connection string in C#. It was defined as a key-value in Azure Deployment configuration files. So this would unfortunately not be relevant. I'll upvote your effort, thanks. – angularsen Oct 07 '12 at 17:32
  • Thanks. I'm glad you figured it out below. – Krzysztof Kozielczyk Oct 07 '12 at 21:27
1

I'm ashamed to realize I had a typo in my connection strings. I was getting connection strings from Azure Deployment configuration files, such as:

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

The typo was included here, at the start of the value string. It must've been a copy'n'paste bug.

This string was duplicated in Azure configuration files Local.cscfg and Cloud.cscfg, for Azure emulator and Azure deployment respectively, as well as in web.config for running locally outside emulator. The typo was only in the Local.cscfg file, which made me very confused when trying to figure out why it did not work in certain scenarios. In addition the typo was for some reason very hard for me to spot. In hindsight I don't see how I didn't figure this out sooner.

angularsen
  • 8,160
  • 1
  • 69
  • 83
0

I don't have a solution yet, but here is my own investigation and theory so far:

I took a look at the source code of WebSecurity.InitializeDatabaseConnection() and think maybe I have found a bug. It doesn't seem to ever set the DatabaseConnectionInfo.Type property, which defaults to ConnectionStringName, which could explain why it doesn't like my connection string, since it would interpret it as a connection string name instead.

WebSecurity class:

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 class:

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,
}
angularsen
  • 8,160
  • 1
  • 69
  • 83
  • I can confirm the behavior OP observed. For anyone who encounters this, even though the API argument names intimate that _either_ a _connection string_ or _connection string name_ can be passed, it, unfortunately, only seems to work with connection string names. The net effect is that it doesn't appear possible with the current version of the Simple Membership API to use the Azure CloudConfigurationManager to resolve the value. My goal was to eliminate the connection string settings in the Web.config, but was not successful. – Bill Craun Apr 15 '13 at 17:27