Jak utworzyć niestandardowe dodatkowe pola w UserProfile w MVC4

Miałem do czynienia z nową funkcją ASP MVC 4, dostarczoną z nowym schematem db członkostwa i nową inicjalizacją. W mvc 3 i starych wersjach programista może tworzyć niestandardowe pola profilu użytkownika za pomocą specyfikacji w Internecie.config, ale teraz miałem do czynienia z metodą w przestrzeni nazw filtrów w domyślnym projekcie mvc 4:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

I tabela profilu użytkownika:

[Table("UserProfile")]
    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
    }

Ale metoda InitializeDatabaseConnection generuje tylko UserName i UserId muszę wygenerować inne dodatkowe pola.

Mam dobre doświadczenie w podejściu do EF codeFirst i w takim przypadku staram się edytować klasę 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; }
    }

Ale kiedy regeneruję bazę danych, nie widzę żadnych zmian, niestandardowe pola Db nie są generowane. Pomóż mi proszę, Jak mogę utworzyć niestandardowe pola użytkownika?

Author: Paul Rasmussen, 2012-09-15

5 answers

Rozwinięcie z powyższej odpowiedzi

Pomoc metody WebSecurity.InitializeDatabaseConnection stwierdza, że

Jeśli chcesz użyć tabeli bazy danych, która zawiera informacje o profilu użytkownika (nazwy użytkowników, adresy e-mail itp.), określ ciąg połączenia i nazwę tabeli, których system członkowski używa do łączenia się z tymi informacjami. Jeśli nie chcesz używać istniejącej tabeli profilu użytkownika, możesz określić, że metoda InitializeDatabaseConnection() powinna automatycznie utworzyć użytkownika tabela profili. (Baza danych dla tabeli profilu użytkownika musi już istnieć.)

Więc jeśli chcemy więcej pól do tabeli UserProfile, musimy się upewnić, że tworzymy tabelę profilu i uruchomić metodę InitializeDatabaseConnection po tym, jak Tabela jest już na miejscu.

W standardowym szablonie projektu MVC4.0 z VS2012 skomentowałem kontroler konta

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{

I przeniósł InitializeDatabaseConnection do pierwszego Inicjalizatora bazy danych EF Code

public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext>
{
    protected override void Seed(MyDatabaseContext context)
    {
        SeedMembership();
    }

    private void SeedMembership()
    {
        WebSecurity.InitializeDatabaseConnection("MyDatabaseContext",
            "UserProfile", "UserId", "UserName", autoCreateTables: true);
    } 
}

Gdy stół jest już na miejscu.

Dodano klasę UserProfile do mojego kodu EF pierwszy model

public class MyDatabaseContext : DbContext
{
    public DbSet<UserProfile> UserProfiles { get; set; }

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

Dodano dodatkowe pole w tabeli 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; }
}

Wszystko, czego teraz potrzebujesz, to ustawić strategię inicjalizacji bazy danych podczas uruchamiania aplikacji, a także wywołać zapytanie w bazie danych, aby upewnić się, że zostanie utworzona w tym momencie, przed wywołaniem kodu autoryzacji/uwierzytelniania.

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);
}
 52
Author: IMLiviu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-24 18:41:02

Wersja nieniszcząca na podstawie odpowiedzi i komentarzy IMLiviu:

Właśnie natknąłem się na ten jeden problem i musiałem unknot poprawny sposób na zrobienie tego z odpowiedzi + komentarze (+próba i błąd), więc pomyślałem, że podzielę się wynikami, które możesz wyciąć i wkleić. Jest to oparte na odpowiedzi przez IMLiviu, więc pełne uznanie dla nich. Modyfikuje istniejące klasy UserProfile i UserContext, ponieważ wydają się być bezpośrednio kompatybilne z EF as-is:

Byłem przerażony widząc sugestię, że związane z całkowitym usunięciem bazy danych, wystarczy dodać kilka tabel, więc po przeczytaniu wszystkich komentarzy i utworzeniu prototypu, oto wynik.

Tworzenie Webmatrix 1 - Stop

Zatrzymaj standardowe tworzenie tabel członkostwa przez webmatrix (skomentuj atrybut [InitializeSimpleMembership]).

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller

2-Utwórz konfigurację migracji

Utwórz klasę konfiguracji migracji, taką jak ta poniżej:

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

3-Usuń pluralizację z EF creation

Zmień Model konta.Klasa pliku cs UsersContext do usunięcia opcji pluralizacji (dodano Zdarzenie 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>();
    }
}

4-Dodaj nowe pola do UserProfile

Dodaj dodatkowe pola potrzebne do 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
}

5-migracja tabel przy starcie aplikacji

Teraz po uruchomieniu aplikacji ustawiasz strategię init bazy danych i uruchamiasz ją z odczytem:

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

Oczywiście będziesz musiał dodać różne wyrażenia, aby uzyskać to wszystko do pracy, ale kliknięcie prawym przyciskiem myszy rozwiąż zrobi to za Ciebie.

Uwagi dodatkowe:

Jeśli zdecydujesz się (tak jak ja) użyć tabeli innej niż UserProfile dla swoich użytkowników, musisz zmienić kilka wpisów, aby dopasować.

  • w swojej klasie SimpleMembershipInitializer musisz odwołać się do nowych nazw tabeli i kolumn
  • w kontrolerze konta i różnych widokach logowania i rejestracji musisz odwołać się do pól nowego modelu (jeśli nazwy mają zmieniony)
  • w klasie UsersContext możesz zostawić nazwę klasy Userprofile jako-is, ale musisz zmienić atrybut Table, aby pasował do nazwy Twojej tabeli.
  • w klasie UserProfile musisz zmienić nazwy pól, aby pasowały do nowych nazw pól tabeli.
  • w bazie danych musisz usunąć relację pomiędzy webpages_UsersInRoles i UserProfile i dodać relację między nową tabelą użytkownika a webpages_UsersInRoles, w przeciwnym razie stare referencyjne kontrole integralności złamie cię w czasie wykonywania. (Zdecydowanie polecam usuwasz istniejącą tabelę UserProfile i sprawdzasz, czy nie została odtworzona. jeśli masz coś w kodzie).
 18
Author: Gone Coding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 10:05:39

Dodaj nową tabelę do bazy danych i nazwij ją User_Details lub podobną, po utworzeniu użytkownika możesz pobrać identyfikator użytkownika i wprowadzić szczegóły do nowej tabeli. Jest to jedna z prostych opcji.

 6
Author: CR41G14,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-07 16:27:45

Spójrz na szablon MVC4 internet project, który został dostarczony z VS2012 lub VS2010. Musisz upewnić się, że baza danych nie jest utworzona przed modyfikacją kolumn klasy userprofile. możesz dodać więcej właściwości w klasach POCO, a następnie zregenerować bazę danych. jeśli dodajesz właściwości po wygenerowaniu bazy danych, upewnij się, że używasz migracji EF, aby dodać te nowe właściwości do bazy danych

 3
Author: pranav rastogi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-16 20:35:57

Oczywiście prawdopodobnie wiesz, że musisz zrobić RegisterModel identyczną z UserProfile Model. Lubię używać migracji przed inicjalizacją bazy danych i umieszczać w pliku 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 
   }

Następnie używam Packet Manager Console za pomocą tych trzech łatwych do zapamiętania poleceń:

  1. Enable-Migrations
  2. Add-Migration MigrationName
  3. Update-Database / / zostanie pobrany z konfiguracji.cs

Zgadzam się zTrueBlueAussie i pójdzie jak mówiąc, że LazyInitialization nie jest już bardzo pomocny i naprawdę nie musisz nazywać tego tak, jak to zrobiłeś. Tak czy inaczej, wszystko co musisz zrobić, to zmienić akcję rejestracji w kontrolerze konta, aby wywołać metodę w ten sposób:

  WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });

Uwaga: MVC5 używa OWIN

 3
Author: yardpenalty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:55