ASP.NET MVC 5 – Identidad. Cómo obtener el ApplicationUser actual

Tengo una entidad Article en mi proyecto que tiene la propiedad ApplicationUser llamada Author . ¿Cómo puedo obtener el objeto completo del ApplicationUser actualmente registrado? Al crear un nuevo artículo, debo establecer la propiedad Author en Article para el Usuario de ApplicationUser actual.

En el antiguo mecanismo de Membresía, era simple, pero en el nuevo enfoque de Identidad no sé cómo hacer esto.

Intenté hacer esto de esa manera:

  • Agregue el uso de la statement para las extensiones de Identidad: using Microsoft.AspNet.Identity;
  • Luego trato de obtener el usuario actual: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

Pero tengo una excepción:

LINQ to Entities no reconoce el método ‘System.String GetUserId (System.Security.Principal.IIdentity)’, y este método no se puede traducir a una expresión de tienda. Source = EntityFramework

    No debería necesitar consultar la base de datos directamente para el ApplicationUser actual.

    Esto introduce una nueva dependencia de tener un contexto adicional para los principiantes, pero en el futuro las tablas de bases de datos de usuarios cambian (3 veces en los últimos 2 años) pero la API es consistente. Por ejemplo, la tabla de users ahora se llama AspNetUsers en Identity Framework, y los nombres de varios campos de claves principales AspNetUsers cambiando, por lo que el código en varias respuestas ya no funcionará como está .

    Otro problema es que el acceso OWIN subyacente a la base de datos utilizará un contexto separado, por lo que los cambios en el acceso SQL por separado pueden producir resultados no válidos (por ejemplo, no ver los cambios realizados en la base de datos). Una vez más, la solución es trabajar con la API suministrada y no intentar solucionarla.

    La forma correcta de acceder al objeto de usuario actual en identidad ASP.Net (como en esta fecha) es:

     var user = UserManager.FindById(User.Identity.GetUserId()); 

    o, si tiene una acción asíncrona, algo como:

     var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 

    FindById requiere que tengas la siguiente statement de uso para que los métodos de UserManager no asíncronos estén disponibles (son métodos de extensión para UserManager, por lo que si no lo incluyes solo verás FindByIdAsync ):

     using Microsoft.AspNet.Identity; 

    Si no está en absoluto en un controlador (por ejemplo, está usando inyección de COI), la ID de usuario se recuperará por completo de:

     System.Web.HttpContext.Current.User.Identity.GetUserId(); 

    Si no está en el controlador de cuenta estándar, deberá agregar lo siguiente (como ejemplo) a su controlador:

    1. Agregue estas dos propiedades:

      ///  /// Application DB context ///  protected ApplicationDbContext ApplicationDbContext { get; set; } ///  /// User manager - attached to application DB context ///  protected UserManager UserManager { get; set; } 

    2. Agregue esto en el constructor del controlador:

      this.ApplicationDbContext = new ApplicationDbContext(); this.UserManager = new UserManager(new UserStore(this.ApplicationDbContext)); 

    Actualización de marzo de 2015

    Nota: La actualización más reciente al marco Identity cambia una de las clases subyacentes utilizadas para la autenticación. Ahora puede acceder desde el contexto de Owin del contenido Http actual.

     ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId()); 

    Apéndice:

    Al usar EF e Identity Framework con Azure, a través de una conexión de base de datos remota (por ejemplo, prueba de host local a la base de datos Azure), puede golpear aleatoriamente el temido “error: 19 – La conexión física no se puede usar”. Como la causa está oculta dentro de Identity Framework, donde no puede agregar rebashs (o lo que parece ser un .Include(x->someTable) faltante .Include(x->someTable) ), debe implementar una SqlAzureExecutionStrategy personalizada en su proyecto.

    Mi error, no debería haber usado un método dentro de una consulta LINQ.

    Código correcto:

     string currentUserId = User.Identity.GetUserId(); ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId); 

    Es en los comentarios de las respuestas, pero nadie ha publicado esto como la solución real.

    Solo necesita agregar una statement de uso en la parte superior:

     using Microsoft.AspNet.Identity; 

    ¡El código de Ellbar funciona! Solo necesitas agregar usando.

    1 – using Microsoft.AspNet.Identity;

    Y … el código de Ellbar:

    2 – string currentUserId = User.Identity.GetUserId(); ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId); string currentUserId = User.Identity.GetUserId(); ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);

    Con este código (en el currentUser ), trabajas los datos generales del usuario conectado, si deseas datos adicionales … mira este enlace

    A partir de ASP.NET Identity 3.0.0, esto se ha refabricado en

     //returns the userid claim value if present, otherwise returns null User.GetUserId(); 
     ApplicationDbContext context = new ApplicationDbContext(); var UserManager = new UserManager(new UserStore(context)); ApplicationUser currentUser = UserManager.FindById(User.Identity.GetUserId()); string ID = currentUser.Id; string Email = currentUser.Email; string Username = currentUser.UserName; 

    En este momento, la plantilla del proyecto asp.mvc crea un controlador de cuenta que obtiene el administrador del usuario de esta manera:

     HttpContext.GetOwinContext().GetUserManager() 

    Lo siguiente funciona para mí:

     ApplicationUser user = HttpContext.GetOwinContext().GetUserManager().FindById(User.Identity.GetUserId()); 

    Para MVC 5 solo mire dentro del método EnableTwoFactorAuthentication de ManageController en el andamio de la plantilla WebApplication, que se realiza allí:

      [HttpPost] [ValidateAntiForgeryToken] public async Task EnableTwoFactorAuthentication() { await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true); var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (user != null) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); } return RedirectToAction("Index", "Manage"); } 

    La respuesta está justo allí, como lo sugiere Microsoft:

     var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 

    Tendrá todas las propiedades adicionales que definió en la clase ApplicationUser.

    Estuve disponible con éxito para obtener el usuario de la aplicación siguiendo la pieza del código

     var manager = new UserManager(new UserStore(new ApplicationDbContext())); var user = manager.FindById(User.Identity.GetUserId()); ApplicationUser EmpUser = user;