net mvc google framework asp c# asp.net-mvc entity-framework asp.net-mvc-4 simplemembership

c# - google - oauth2 asp net mvc



Cómo crear campos adicionales personalizados en UserProfile en MVC4 (5)

Me enfrenté a la nueva característica ASP MVC 4, que se envía con un nuevo esquema db de membresía y una nueva inicialización. En mvc 3 y versiones anteriores, el desarrollador puede crear campos de perfil de usuario personalizados usando especificaciones en web.config, pero ahora me enfrenté al método en el espacio de nombres de filtros en el proyecto mvc 4 predeterminado:

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

y tabla de perfil de usuario:

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

Pero el método InitializeDatabaseConnection genera solo UserName y UserId. Necesito generar otros campos adicionales.

Tengo una buena experiencia en el enfoque de EF codeFirst, y en ese caso intento editar UserProfile Class:

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

Pero cuando regenero la base de datos, no veo ningún cambio, no se generan campos de Db personalizados. Ayúdame, por favor, ¿cómo puedo crear campos de usuario personalizados?


Versión no destructiva basada en las respuestas y comentarios de IMLiviu:

Solo encontré este problema y tuve que deshacer la forma correcta de hacerlo desde la respuesta + comentarios (+ prueba y error), así que pensé en compartir los resultados que puedes cortar y pegar. Esto se basa en la respuesta de IMLiviu, así que crédito total para ellos. Modifica las clases UserProfile y UserContext existentes, ya que parecen directamente compatibles con EF tal como está:

Me horroricé al ver una sugerencia que implicaba eliminar por completo una base de datos, solo para agregar algunas tablas, así que después de leer todos los comentarios y crear un prototipo, este es el resultado.

1 - Detener la creación de Webmatrix

Detenga la creación estándar de webmatrix de las tablas de miembros (comente el atributo [InitializeSimpleMembership]).

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

2 - Crea una configuración de migración

Cree una clase de configuración de migración como la siguiente:

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 - Eliminar la pluralización de la creación EF

Cambie el archivo UsersContext clase UsersContext para eliminar la opción de pluralización (agregó el evento 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 - Agregue nuevos campos a UserProfile

Agregue los campos adicionales que necesita a 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 - Migrar las tablas al inicio de la aplicación

Ahora, cuando se inicia la aplicación, configura la estrategia init de la base de datos y la activa con una lectura:

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

Obviamente, deberá agregar varias instrucciones de uso para que todo funcione, pero la opción de clic con el botón derecho lo hará por usted.

Notas adicionales:

Si decide (como yo lo hice) usar una tabla que no sea UserProfile para sus usuarios, debe cambiar varias entradas para que coincidan.

  • En su clase SimpleMembershipInitializer , necesita hacer referencia a los nuevos nombres de tabla y columna
  • En el controlador de cuenta y en las diversas vistas de inicio de sesión y registro, debe hacer referencia a los nuevos campos de modelo (si los nombres han cambiado)
  • En la clase UsersContext puede dejar el UsersContext clase UsersContext tal cual, pero debe cambiar el atributo Table para que coincida con el nombre de su tabla.
  • En la clase UserProfile necesita cambiar el nombre de los campos para que coincidan con los nuevos nombres de campo de la tabla.
  • En la base de datos debe eliminar la relación entre las webpages_UsersInRoles UserProfile y UserProfile y agregar una relación entre su nueva tabla de usuarios y las webpages_UsersInRoles o las antiguas comprobaciones de integridad referencial le interrumpirán en el tiempo de ejecución. (Recomiendo encarecidamente que elimine la tabla de UserProfile existente y compruebe que no se vuelva a crear, si es que tiene algo olvidado en el código).

Agregue una nueva tabla a la base de datos y llámela User_Details o similar; al crear un usuario, puede recuperar la identificación del usuario y forzar los detalles en la nueva tabla. Esta es una opción simple.


Eche un vistazo a la plantilla de proyecto de Internet MVC4 que se envió con VS2012 o VS2010. Debe asegurarse de que la base de datos no se haya creado antes de modificar las columnas de su clase de perfil de usuario. puede agregar más propiedades en sus clases de POCO y luego regenerar su base de datos. Si agrega propiedades después de generar la base de datos, asegúrese de estar utilizando migraciones EF para agregar esas nuevas propiedades a la base de datos.


Elaborando a partir de la respuesta anterior

El método de WebSecurity.InitializeDatabaseConnection indica que

Si desea utilizar una tabla de base de datos que contenga información de perfil de usuario (nombres de usuario, direcciones de correo electrónico, etc.), especifique una cadena de conexión y un nombre de tabla que el sistema de membresía usa para conectarse a esa información. Si no desea utilizar una tabla de perfil de usuario existente, puede especificar que el método InitializeDatabaseConnection () cree automáticamente la tabla de perfil de usuario. (Una base de datos para la tabla de perfil de usuario ya debe existir).

Entonces, si queremos más campos en la tabla UserProfile solo necesitamos asegurarnos de que estamos creando una tabla de perfiles y ejecutar el método InitializeDatabaseConnection vez que la tabla ya esté en su lugar.

En la plantilla de proyecto MVC4.0 estándar de VS2012, he comentado el controlador de la cuenta

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

y movió InitializeDatabaseConnection en el primer inicializador de base de datos del código EF

public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext> { protected override void Seed(MyDatabaseContext context) { SeedMembership(); } private void SeedMembership() { WebSecurity.InitializeDatabaseConnection("MyDatabaseContext", "UserProfile", "UserId", "UserName", autoCreateTables: true); } }

asegurando que InitializeDatabaseConnection ejecute una vez que la tabla ya esté en su lugar.

Se agregó la clase UserProfile a mi primer modelo de EF Code

public class MyDatabaseContext : DbContext { public DbSet<UserProfile> UserProfiles { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } }

Se agregó el campo adicional en la tabla 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; } }

Todo lo que necesita ahora es establecer la estrategia de inicialización de la base de datos cuando se inicia la aplicación y también llamar a una consulta en la base de datos para asegurarse de que se cree en ese punto, antes de llamar a cualquier código de autorización / autenticación.

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


Por supuesto, probablemente sepa que tiene que hacer que su UserProfile Model RegisterModel idéntico al UserProfile Model de UserProfile Model . Lo que me gusta hacer es usar Migraciones antes de inicializar la base de datos y poner lo siguiente en el archivo 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 }

Luego utilizo Packet Manager Console con estos tres comandos fáciles de recordar:

  1. Habilitar migraciones
  2. Add-Migration MigrationName
  3. La base de datos de actualización // generará desde Configuration.cs

Estoy de acuerdo con TrueBlueAussie , e iría tan lejos como para decir que LazyInitialization ya no es muy útil y no es necesario que lo llames como siempre lo hiciste. De todos modos, todo lo que tienes que hacer es cambiar tu acción de registro en el controlador de tu cuenta para llamar al método de esta manera:

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

NOTA: MVC5 usa OWIN