新しいASP= MVC 4機能に直面しました。新しいメンバーシップデータベーススキーマと新しい初期化が付属しています。mvc3および古いバージョンの開発者はweb.configの仕様を使用してカスタムユーザープロファイルフィールドを作成でき、しかし今、私はデフォルトのMVC 4プロジェクトのフィルタ名前空間のメソッドに直面しました:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
およびユーザープロファイルテーブル:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
ただし、InitializeDatabaseConnectionメソッドは、他の追加フィールドを生成する必要があるUserNameとUserIdのみを生成します。
私はEF codeFirstアプローチの良い経験があり、その場合、UserProfileクラスを編集しようとします:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Column]
[Required]
public string UserName { get; set; }
[Column]
[Required]
public string FirstName { get; set; }
[Column]
[Required]
public string LastName { get; set; }
}
しかし、データベースを再生成すると、カスタムDbフィールドが生成されず、変更が表示されません。カスタムユーザーフィールドを作成するにはどうすればよいですか?
上記の答えから詳しく説明する
WebSecurity.InitializeDatabaseConnection
メソッドヘルプは、
ユーザープロファイル情報(ユーザー名、電子メールアドレスなど)を含むデータベーステーブルを使用する場合は、メンバーシップシステムがその情報への接続に使用する接続文字列とテーブル名を指定します。既存のユーザープロファイルテーブルを使用しない場合は、InitializeDatabaseConnection()メソッドがユーザープロファイルテーブルを自動的に作成するように指定できます。 (ユーザープロファイルテーブルのデータベースが既に存在している必要があります。)
したがって、UserProfile
テーブルにさらにフィールドが必要な場合は、プロファイルテーブルを作成し、テーブルが既に配置された後にInitializeDatabaseConnection
メソッドを実行していることを確認するだけです。
VS2012の標準MVC4.0プロジェクトテンプレートで、アカウントコントローラーをコメントアウトしました
[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{
InitializeDatabaseConnection
をEF Code First Database Initializerに移動しました
public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext>
{
protected override void Seed(MyDatabaseContext context)
{
SeedMembership();
}
private void SeedMembership()
{
WebSecurity.InitializeDatabaseConnection("MyDatabaseContext",
"UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
テーブルが既に配置されたら、InitializeDatabaseConnection
が実行されるようにします。
EF Code FirstモデルにUserProfile
クラスを追加しました
public class MyDatabaseContext : DbContext
{
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
UserProfile
テーブルに追加フィールドを追加しました
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string MobilePhone { get; set; }
}
ここで必要なのは、アプリケーションの起動時にデータベース初期化戦略を設定し、データベースでクエリを呼び出して、その時点で認証/認証コードが呼び出される前に作成されることを確認することです。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Database.SetInitializer<MyDatabaseContext>(new MyDatabaseInit());
new MyDatabaseContext().UserProfile.Find(1);
}
この1つの問題に出くわし、nknot回答+コメント(+試行錯誤)からそれを行う正しい方法が必要だったため、カットアンドペーストできる結果を共有すると思いました。これは、IMLiviuの回答に基づいているため、完全にクレジットされています。既存のUserProfile
およびUserContext
クラスは、EFと直接互換性があるように変更されます。
すべてのコメントを読んでプロトタイプを作成した後、いくつかのテーブルを追加するだけでデータベースを完全に削除するという提案を見て、私はぞっとしました。結果は次のとおりです。
メンバーシップテーブルの標準webmatrix作成を停止します([InitializeSimpleMembership]属性をコメントアウトします)。
[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
以下のような移行構成クラスを作成します。
public class MigrationConfiguration : DbMigrationsConfiguration<UsersContext>
{
public MigrationConfiguration()
{
this.AutomaticMigrationsEnabled = true; // This is important as it will fail in some environments (like Azure) by default
}
protected override void Seed(UsersContext context)
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
AccountModel.csファイルUsersContext
クラスを変更して、複数形オプション(OnModelCreatingイベントを追加)を削除します。
public class UsersContext : DbContext
{
public UsersContext() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
必要な追加フィールドをUserProfileに追加します。
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; } // <<<<<<<< E.G. THIS ADDED
}
アプリが起動したら、データベースの初期化戦略を設定し、読み取りでトリガーします。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Database.SetInitializer(new MigrateDatabaseToLatestVersion<UsersContext, MigrationConfiguration>());
new UsersContext().UserProfiles.Find(1);
}
もちろん、これをすべて機能させるにはさまざまなusingステートメントを追加する必要がありますが、右クリックresolveオプションを使用すると自動的に実行されます。
(私がしたように)UserProfile
以外のテーブルをユーザーに使用することに決めた場合、一致するようにいくつかのエントリを変更する必要があります。
SimpleMembershipInitializer
クラスでは、新しいテーブル名と列名を参照する必要がありますUsersContext
クラスでは、Userprofileクラス名をそのままにすることができますが、テーブル名に一致するようにTable
属性を変更する必要があります。UserProfile
クラスでは、新しいテーブルフィールド名に一致するようにフィールドの名前を変更する必要があります。webpages_UsersInRoles
とUserProfile
の関係を削除し、新しいユーザーテーブルとwebpages_UsersInRoles
の関係を追加する必要があります。そうしないと、実行時に古い参照整合性チェックによって問題が発生します。 。 (既存のUserProfile
テーブルを削除し、再作成されないことを確認することを強くお勧めします。コードに何かが残っている場合は)。データベースに新しいテーブルを追加し、User_Detailsまたは同様の名前で呼び出します。ユーザーの作成時に、ユーザーのIDを取得し、詳細を新しいテーブルに強制できます。これは1つの簡単なオプションです。
VS2012またはVS2010に同梱されているMVC4インターネットプロジェクトテンプレートをご覧ください。 userprofileクラスの列を変更する前に、データベースが作成されていないことを確認する必要があります。 POCOクラスにさらにプロパティを追加してから、データベースを再生成できます。データベースの生成後にプロパティを追加する場合は、EF移行を使用してそれらの新しいプロパティをデータベースに追加していることを確認してください
もちろん、あなたはRegisterModel
をUserProfile Model
と同一にする必要があることをおそらく知っているでしょう。私がやりたいのは、データベースを初期化する前にMigrationsを使用し、Configuration.cs
ファイルに以下を入れることです。
protected override void Seed(UsersContext context)
{
WebSecurity.InitializeDatabaseConnection(
"DefaultConnection",
"UserProfile",
"UserId",
"UserName", autoCreateTables: true);
if (!WebSecurity.UserExists("yardpenalty"))
WebSecurity.CreateUserAndAccount(
"yardpenalty",
"password",
new
{
Email = "[email protected]",
ImageUrl = "/Content/Avatars/yourname",
DateJoined = DateTime.Now
},
false);
//... rest of model.Builder stuff
}
次に、覚えやすい次の3つのコマンドでPacket Manager Console
を使用します。
私は TrueBlueAussie に同意し、LazyInitializationはもはやあまり役に立たず、もはやあなたがやったようにそれを呼ぶ必要はないということまで行きます。とにかく、あなたがしなければならないのは、次のようにメソッドを呼び出すように、アカウントコントローラーで登録アクションを変更することです:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });
注:MVC5はOWINを使用します