it-swarm.com.de

ASP.NET MVC 5 - Identität. So erhalten Sie den aktuellen ApplicationUser

Ich habe eine Artikelentität in meinem Projekt, deren ApplicationUser-Eigenschaft Author lautet. Wie kann ich das vollständige Objekt der aktuell protokollierten ApplicationUser abrufen? Beim Erstellen eines neuen Artikels muss ich die Author-Eigenschaft in Article auf das aktuelle ApplicationUser setzen.

Im alten Mitgliedschaftsmechanismus war es einfach, aber im neuen Identitätsansatz weiß ich nicht, wie das geht.

Ich habe es so versucht:

  • Fügen Sie using-Anweisung für Identitätserweiterungen hinzu: using Microsoft.AspNet.Identity;
  • Dann versuche ich den aktuellen Benutzer zu bekommen: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

Ich bekomme aber folgende Ausnahme:

LINQ to Entities erkennt die Methode 'System.String GetUserId (System.Security.Principal.IIdentity)' nicht. Diese Methode kann nicht in einen Speicherausdruck ..__ übersetzt werden. Source = EntityFramework

221
Ellbar

Sie sollten die Datenbank nicht direkt nach dem aktuellen ApplicationUser abfragen.

Dies führt zu einer neuen Abhängigkeit, einen zusätzlichen Kontext für Starter zu haben, aber in der Zukunft ändern sich die Benutzerdatenbanktabellen (3-mal in den letzten 2 Jahren), die API ist jedoch konsistent. Zum Beispiel heißt die users-Tabelle in Identity Framework jetzt AspNetUsers, und die Namen mehrerer Primärschlüsselfelder wurden ständig geändert, so dass der Code in mehreren Antworten nicht mehr funktioniert as-is.

Ein anderes Problem besteht darin, dass der zugrunde liegende OWIN-Zugriff auf die Datenbank einen separaten Kontext verwendet, sodass Änderungen durch einen separaten SQL-Zugriff zu ungültigen Ergebnissen führen können (z. B. keine Änderungen an der Datenbank). Wieder ist die Lösung, Arbeit mit der bereitgestellten API und nicht Umgehung zu versuchen.

Der korrekte Weg, um auf das aktuelle Benutzerobjekt in ASP.Net-Identität (bis zu diesem Datum) zuzugreifen, ist:

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

oder, wenn Sie eine asynchrone Aktion haben, etwas wie:

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

Für FindById müssen Sie die folgende using-Anweisung verwenden, damit die nicht asynchronen UserManager-Methoden verfügbar sind (sie sind Erweiterungsmethoden für UserManager. Wenn Sie dies nicht angeben, wird nur FindByIdAsync angezeigt:

using Microsoft.AspNet.Identity;

Wenn Sie sich überhaupt nicht in einem Controller befinden (z. B. verwenden Sie die Injektion IOC), wird die Benutzer-ID vollständig abgerufen von:

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

Wenn Sie sich nicht im Standard-Kontocontroller befinden, müssen Sie Ihrem Kontroller Folgendes hinzufügen (als Beispiel):

1. Fügen Sie diese beiden Eigenschaften hinzu:

    /// <summary>
    /// Application DB context
    /// </summary>
    protected ApplicationDbContext ApplicationDbContext { get; set; }

    /// <summary>
    /// User manager - attached to application DB context
    /// </summary>
    protected UserManager<ApplicationUser> UserManager { get; set; }

2. Fügen Sie dies im Konstruktor des Controllers hinzu:

    this.ApplicationDbContext = new ApplicationDbContext();
    this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));

Update März 2015

Hinweis: Die letzte Aktualisierung des Identity-Frameworks ändert eine der für die Authentifizierung verwendeten zugrunde liegenden Klassen. Sie können jetzt über den Owin-Kontext des aktuellen HttpContent darauf zugreifen.

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

Nachtrag:

Wenn Sie EF und Identity Framework mit Azure über eine Remote-Datenbankverbindung verwenden (z. B. Testen eines lokalen Hosts mit der Azure-Datenbank), können Sie den gefürchteten "Fehler: 19 - Physikalische Verbindung ist nicht verwendbar" zufällig treffen. Da die Ursache in Identity Framework verankert ist, wo Sie keine Wiederholungsversuche hinzufügen können (oder was .Include(x->someTable) fehlt), müssen Sie eine benutzerdefinierte SqlAzureExecutionStrategy in Ihrem Projekt implementieren.

416
Gone Coding

Mein Fehler, ich hätte keine Methode in einer LINQ-Abfrage verwenden sollen.

Korrekter Code:

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

Es ist in den Kommentaren der Antworten, aber niemand hat dies als die eigentliche Lösung gepostet.

Sie müssen nur eine using-Anweisung oben einfügen:

using Microsoft.AspNet.Identity;
29
rtpHarry

Der Code von Ellbar funktioniert! Sie müssen nur noch mit hinzufügen.

1 - using Microsoft.AspNet.Identity;

Und ... der Code von Ellbar:

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

Mit diesem Code (in currentUser) arbeiten Sie die allgemeinen Daten des verbundenen Benutzers, wenn Sie zusätzliche Daten wünschen ... siehe diesen Link

9
Diego Borges

Seit ASP.NET Identity 3.0.0 wurde dies in umgestaltet

//returns the userid claim value if present, otherwise returns null
User.GetUserId();
6
Seth IK
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
ApplicationUser currentUser = UserManager.FindById(User.Identity.GetUserId());

string ID = currentUser.Id;
string Email = currentUser.Email;
string Username = currentUser.UserName;
5
Majid joghataey

Im Moment erstellt die Projektvorlage von asp.mvc einen Account-Controller, der den Usermanager auf diese Weise abruft:

HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>()

Folgendes funktioniert für mich:

ApplicationUser user = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(User.Identity.GetUserId());
3
Holger Thiemann

Für MVC 5 müssen Sie nur die EnableTwoFactorAuthentication-Methode von ManageController im WebApplication-Vorlagengerüst betrachten.

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> 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");
        }

Die Antwort ist genau da, wie von Microsoft selbst vorgeschlagen:

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

Sie verfügt über alle zusätzlichen Eigenschaften, die Sie in der ApplicationUser-Klasse definiert haben.

1
Paceman

Falls jemand mit Identity-Benutzern in web forms arbeitet, habe ich es dadurch zur Wirkung gebracht:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());
0
Jamshaid Kamran

Ich war erfolgreich verfügbar, um Application User Byfolge Code zu erhalten

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
            var user = manager.FindById(User.Identity.GetUserId());
            ApplicationUser EmpUser = user;
0
Abdul Hannan