Как создать пользовательские дополнительные поля в UserProfile в MVC4
я столкнулся с новой функцией ASP MVC 4, она поставляется с новой схемой членства в БД и новой инициализацией. В MVC 3 и старых версиях разработчик может создавать пользовательские поля профиля пользователя, используя спецификации в интернете.config, но теперь я столкнулся с методом в пространстве имен filters в проекте 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 генерирует только имя пользователя и 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; }
}
но когда я восстановить базу данных, я не вижу никаких изменений, пользовательские поля БД не создается. Помогите мне пожалуйста, как я могу создавать пользовательские поля?
5 ответов
разработка из ответа выше
на WebSecurity.InitializeDatabaseConnection
метод help заявляет, что
если вы хотите использовать таблицу базы данных, содержащую сведения о профиле пользователя (имена пользователей, адреса электронной почты и т. д.), укажите строку подключения и имя таблицы, которые система членства использует для подключения к этой информации. Если вы не хотите использовать существующую таблицу профилей пользователей, можно указать, что метод InitializeDatabaseConnection() должен автоматическое создание таблицы профилей пользователей. (База данных для таблицы профилей пользователей должна уже существовать.)
Итак, если мы хотим больше полей в UserProfile
таблица нам просто нужно убедиться, что мы создаем таблицу профилей и запускаем InitializeDatabaseConnection
метод после того, как таблица уже на месте.
в стандартном MVC4.0 шаблон проекта от VS2012 я прокомментировал контроллер учетной записи
[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{
и двигался InitializeDatabaseConnection
в код EF сначала Инициализатор Базы Данных
public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext>
{
protected override void Seed(MyDatabaseContext context)
{
SeedMembership();
}
private void SeedMembership()
{
WebSecurity.InitializeDatabaseConnection("MyDatabaseContext",
"UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
убедившись, что InitializeDatabaseConnection
запускается, как только таблица уже на месте.
добавил UserProfile
класс для моей первой модели кода EF
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);
}
неразрушающая версия, основанная на ответе и комментариях IMLiviu:
просто наткнулся на эту проблему и должен был unknot правильный способ сделать это из ответа + комментариев (+ проб и ошибок), поэтому я думал, что поделюсь результатами, которые вы можете вырезать и вставить. Это основано на ответе Имливиу, поэтому полный кредит им. Он изменяет существующий UserProfile
и UserContext
классы, как они появляются непосредственно совместимы с EF as-is:
Я был в ужасе чтобы увидеть предложение, которое включало полное удаление базы данных, просто добавьте несколько таблиц, чтобы после прочтения всех комментариев и создания прототипа, вот результат.
1 - остановить создание Webmatrix
остановите стандартное создание WebMatrix таблиц членства (прокомментируйте атрибут [InitializeSimpleMembership]).
[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
2-создать конфигурацию миграции
создайте класс конфигурации миграции, такой как ниже:
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-Удалить плюрализацию из EF creation
измените 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>();
}
}
4-Добавление новых полей в UserProfile
добавьте дополнительные поля, необходимые для 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-перенос таблиц на app start
теперь, когда приложение запускается, вы устанавливаете стратегию инициализации базы данных и запускаете это с надписью:
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, чтобы все это работало, но щелкните правой кнопкой мыши разрешить опция сделает это за вас.
дополнительная информация:
если вы решите (как я) использовать таблицу, отличную от UserProfile
для ваших пользователей вам нужно изменить несколько записей в соответствии.
- в своем
SimpleMembershipInitializer
class вам нужно ссылаться на новую таблицу и столбец имена - в контроллере учетной записи и различных представлениях входа и регистрации вам нужно ссылаться на поля новой модели (если имена изменились)
- на
UsersContext
class вы можете оставить имя класса Userprofile как есть, но вам нужно изменитьTable
атрибут, соответствующий имени таблицы. - на
UserProfile
class вам нужно переименовать поля, чтобы соответствовать вашим новым именам полей таблицы. - в базе данных необходимо удалить отношения между
webpages_UsersInRoles
иUserProfile
и добавьте связь между вашей новой таблицей пользователя иwebpages_UsersInRoles
или старые проверки целостности ссылок сломают вас во время выполнения. (Я настоятельно рекомендую вам удалить существующийUserProfile
таблица и проверьте, что она не воссоздана. если у вас что-то осталось в вашем коде).
добавьте новую таблицу в базу данных и назовите ее User_Details или аналогичной, при создании пользователя вы можете получить идентификатор пользователя и принудительно ввести данные в новую таблицу. Это один простой вариант.
посмотрите на шаблон интернет-проекта MVC4, который поставляется с VS2012 или на VS2010. Перед изменением столбцов класса userprofile необходимо убедиться, что база данных не создана. можно добавить дополнительные свойства в классы POCO, а затем восстановить базу данных. если вы добавляете свойства после создания базы данных, убедитесь, что вы используете миграции EF для добавления этих новых свойств в базу данных
конечно, вы, вероятно, знаете, что вы должны сделать свой RegisterModel
идентичны UserProfile Model
. Что мне нравится делать, так это использовать миграции до инициализации базы данных и поместить следующее в :
protected override void Seed(UsersContext context)
{
WebSecurity.InitializeDatabaseConnection(
"DefaultConnection",
"UserProfile",
"UserId",
"UserName", autoCreateTables: true);
if (!WebSecurity.UserExists("yardpenalty"))
WebSecurity.CreateUserAndAccount(
"yardpenalty",
"password",
new
{
Email = "youremail@yahoo.com",
ImageUrl = "/Content/Avatars/yourname",
DateJoined = DateTime.Now
},
false);
//... rest of model.Builder stuff
}
тогда я использую Packet Manager Console
этими тремя легко запомнить команды:
- Включить-Миграций
- Добавить-Миграция MigrationName
- Update-Database / / будет семя из конфигурации.cs
I согласитесь с TrueBlueAussie, и дошел бы до того, что сказал, что LazyInitialization больше не очень полезен, и вам действительно не нужно называть это так, как вы это сделали. В любом случае, все, что вам нужно сделать, это изменить действие регистрации в контроллере учетной записи, чтобы вызвать метод следующим образом:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });
Примечание: MVC5 использует OWIN