0

ASP.NET MVC 4 SimpleMembership を「すぐに」使用しています。

認証要件をコントローラーの deco として設定しました[Authorize(Roles = "User")].

ログアウトせずにウェブサイトを離れる場合を除いて、正常に機能します。次回戻ってきたときRequest.IsAuthenticatedはまだ真実ですが、ビューに移動すると「A network-related or instance-specific error occurred while establishing a connection to SQL.」が表示されます実際には、ローカルデータベースに接続しようとしているようです:"SQLExpress database file auto-creation error'- App_Dataフォルダー内。しかし、これを指す接続文字列はありません。すべて Azure Sql 上にあります。

これが何か分かりますか?そして、なぜログインしたままのふりをするのでしょうか? そして、なぜデータベースを作成しようとしたのでしょうか?

------------------------------------Stack trace-------------------------------------------

[SqlException (0x80131904): 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: 26 - Error Locating Server/Instance Specified)]
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5296071
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +558
   System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover) +5308555
   System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) +145
   System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) +889
   System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) +307
   System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions) +434
   System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) +5311099
   System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) +38
   System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) +5313314
   System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) +143
   System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) +83
   System.Data.SqlClient.SqlConnection.Open() +96
   System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) +76

[HttpException (0x80004005): Unable to connect to SQL Server database.]
   System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) +131
   System.Web.Management.SqlServices.SetupApplicationServices(String server, String user, String password, Boolean trusted, String connectionString, String database, String dbFileName, SqlFeatures features, Boolean install) +89
   System.Web.Management.SqlServices.Install(String database, String dbFileName, String connectionString) +27
   System.Web.DataAccess.SqlConnectionHelper.CreateMdfFile(String fullFileName, String dataDir, String connectionString) +386
4

2 に答える 2

0

SimpleMembershipの「すぐに使える」設定を使用している場合は、Cookieを使用してユーザーのログインを維持します。SimpleMembershipはEFコードファーストを使用し、データベースがすでに存在するとは思わない場合はデータベースの作成を試みます。遅延読み込みメカニズムを使用しているため、AccountControllerにアクセスするまで(つまり、ログオンページまたは登録ページに移動するまで)作成を試みません。承認に失敗すると、ログオンページにリダイレクトされます。「すぐに使用できる」設定を使用している場合は、DefaultConnectionという名前のweb.configの接続文字列を使用する必要があります。こんな感じになります

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

ProjectNameは、MVC4インターネットテンプレートを使用して最初に作成したときのMVCプロジェクトの名前です。Azureで動作するようにこれを変更することをお勧めします。

2013年3月7日更新 デフォルトの接続文字列を使用していないため、2か所で使用する接続文字列を更新する必要があります。イニシャライザで更新したとおっしゃっていたので、次のようなコードを持つSimpleMembershipInitializerを意味していると思います。

    public SimpleMembershipInitializer()
    {
        Database.SetInitializer<UsersContext>(null);

        try
        {
            using (var context = new UsersContext())
            {
                if (!context.Database.Exists())
                {
                    // Create the SimpleMembership database without Entity Framework migration schema
                        ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                }
            }

            WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
        }

(質問にコードを指定しなかったため)接続文字列の名前を使用するようにInitializeDatabaseConnectionの最初のパラメーターを更新したと想定しています。これは良いことですが、データベース接続の構成のみを処理します。データベースが作成されているかどうかを検出し、実際にデータベースを作成しているコードを見ると、この接続の設定を上回っています。接続文字列は、AccountModels.csにあるUserContextでも設定されます。このためのコードは

public UsersContext()
    : base("DefaultConnection")
{
}

ご覧のとおり、接続文字列はベースコンテキストに渡されます。ここで変更しなかった場合は、DefaultConnection接続文字列を使用して存在を確認し、作成を試みます。接続文字列が欠落している場合は、DefaultConnectionというローカルデータベースを作成しようとすると思います。

フォーム認証を使用している場合は、この記事で説明されているように、初期化子を取り除いて自分で処理することをお勧めします。この初期化子は、開発者がフォーム認証を使用したくない場合にテンプレートで生成されたコードが機能するように設計されています。

于 2013-03-06T20:21:36.730 に答える
0

私はついにこの問題を理解しました!このスレッドを見つけたときも同じ問題を抱えていましたが、決定的な答えがなかったため、自分で調べなければなりませんでした。

何が起こるかというと、UsersContext は最終的にその接続を追跡できなくなります。UserContext を完全にバイパスし、コンストラクターを回避することで、接続は安定したままになります。

注: 単純なメンバーシップ テーブルを自動生成しないので、その場合にうまくいくかどうかはわかりません。

こちらの AccountModels.cs の UsersContext を参照してください。このコードはコメントアウトまたは削除する必要があります。

public class UsersContext : DbContext
{
    public UsersContext()
        : base("YourDBContext")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<webpages_Membership> webpages_Memberships { get; set; }
    public DbSet<UsersInRole> webpages_UsersInRoles { get; set; }
    public DbSet<Role> webpages_Roles { get; set; }
}

UsersContext から DbSets を独自のコンテキストに追加します。

public class YourDBContext : DbContext
{
    public DbSet<Blah> Blahs{ get; set; }
    public DbSet<Something> Somethings { get; set; }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<webpages_Membership> webpages_Memberships { get; set; }
    public DbSet<UsersInRole> webpages_UsersInRoles { get; set; }
    public DbSet<Role> webpages_Roles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

}

もちろん、すべてを行った後は、UsersContext への参照をすべて YourDBContext に変更する必要があります。つまり、

UsersContext uc = new UsersContext();

なる

YourDBContext ydb = new YourDBContext();

これを行うことの追加の利点は、2 つの異なる DBContext を追跡する必要がないことです。

于 2013-08-20T20:45:02.280 に答える