1

SimpleMembership を使用してデータベース接続を初期化しようとすると、このエラー メッセージが表示されます。最初の初期化ステートメントは通過しますが、2 番目のステートメントは通過しません。目標は、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、およびデフォルトの SimpleMembership 構造を持つ MVC4 RTM。

完全なスタック トレース:

[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
4

3 に答える 3

1

接続文字列にタイプミスがあったことに気づいて恥ずかしいです。次のようなAzureDeployment構成ファイルから接続文字列を取得していました。

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

タイプミスは、値文字列の先頭に含まれています。コピーアンドペーストのバグだったに違いありません。

この文字列は、AzureエミュレーターとAzureデプロイメント用にそれぞれAzure構成ファイルLocal.cscfgとCloud.cscfgに複製され、エミュレーターの外部でローカルに実行するためにweb.configに複製されました。タイプミスはLocal.cscfgファイルにのみ含まれていたため、特定のシナリオでタイプミスが機能しなかった理由を理解しようとすると、非常に混乱しました。さらに、タイプミスは私が見つけるのが非常に難しい理由でした。後から考えると、どうしてこれを早く理解できなかったのかわかりません。

于 2012-10-07T17:42:16.967 に答える
1

この投稿で説明されているように、二重エスケープ (\\v11.0の代わりに実行)の欠如に苦しんでいるように思えます。\v11.0

于 2012-10-07T17:18:59.713 に答える
0

まだ解決策はありませんが、これまでの私自身の調査と理論は次のとおりです。

WebSecurity.InitializeDatabaseConnection() のソース コードを調べたところ、おそらくバグが見つかったと思います。代わりに接続文字列名として解釈されるため、接続文字列が気に入らない理由を説明できます。

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,
}
于 2012-10-07T11:53:15.217 に答える