0

Ich versuche, herauszufinden, was der berechtigte Benutzer zur Zeit versucht, die Daten zu speichern und die E-Mail aufnehmen.aktualisieren gemeinsames Feld mit Benutzer E-Mail

Ich habe eine Grundeinstellung in meinem DbContext, die das Update für Zeitstempel tun, aber ich kann nicht herausfinden, wie die Benutzerinformationen zuzugreifen:

public override int SaveChanges() 
{ 
    AddTimestamps(); 
    return base.SaveChanges(); 
} 


public override async Task<int> SaveChangesAsync() 
     { 
      AddTimestamps(); 
      return await base.SaveChangesAsync(); 
     } 

    private void AddTimestamps() 
    { 
     var entities = ChangeTracker.Entries() 
      .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified); 

     var currentUser = "[email protected]" // This i haven't been able to figure out how to retrieve 

     foreach (var entity in entities) 
     { 
      if (entity.State == EntityState.Added) 
      { 
       ((BaseEntity)entity.Entity).DateCreated = DateTime.UtcNow; 
       ((BaseEntity)entity.Entity).CreatedBy = currentUsername; 
      } 

      ((BaseEntity)entity.Entity).DateModified = DateTime.UtcNow; 
      ((BaseEntity)entity.Entity).ModifiedBy = currentUsername; 
     } 
    } 
} 

bisschen mehr von einem Hintergrund das alles auf ASP-Core gebaut 2 und EF Kern. Der DBContext befindet sich in meinem APIContoso-Projekt, das den benutzerdefinierten Identitätsanbieter IDPContoso verwendet, der auf ASP Core 2 und Identity Server4 basiert.

Wie kann ich die Benutzer-E-Mail innerhalb des DBContext erhalten, damit ich sie aufzeichnen kann?

+0

Ho haben Sie implementiert 'DbContext' ist es, abgeleitet von' IdentityDbContext' oder Sie implementieren benutzerdefinierte Authentifizieren während 'SavaChange' . – Aria

+0

ChangeTracker.Entries ermöglicht es Ihnen, alle angeschlossenen Einträge eines bestimmten Typs zu bekommen, anstatt sie zu werfen und möglicherweise in eine Null-Referenz ausgeführt werden. – DevilSuichiro

Antwort

1

Ich schlage vor, Sie die E-Mail von der Identität erhalten. Auf diese Weise benötigen Sie keinen zusätzlichen Aufruf an die Datenbank. Wenn Sie die E-Mail zum Anmelden verwenden, enthält User.Identity.Name die E-Mail (falls sie korrekt zugeordnet wurde). Andernfalls fügen Sie einen Anspruch hinzu, der die E-Mail enthält.

Jetzt müssen Sie die E-Mail in das Modell injizieren. Ich gehe von einem getrennten Projekt für das Modell aus. In diesem Fall können Sie nicht einfach IHttpContextAccessor injizieren. Andernfalls können Sie einfach IHttpContextAccessor injizieren und die Benutzerinformationen lesen, wenn das Modell erstellt wird.

Der folgende Code dient nur zu Demonstrationszwecken. In Startup.cs ein Objekt injizieren, die die connection enthält:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddScoped(provider => new Database.ConnectionInfo 
    { 
     ConnectionString = provider.GetRequiredService<ApplicationSettings>().ConnectionString, 
     User = provider.GetRequiredService<IHttpContextAccessor>().HttpContext.User?.Identity.Name 
    }); 
    services.AddScoped<Model>(); 
} 

Da diese scoped wird, wird jedesmal, wenn ein Benutzer eine Verbindung, die Benutzerinformationen einstellen. Für anonyme Benutzer ist User = null. Beachten Sie, dass das Modell selbst ebenfalls einem Bereich unterliegt. Die connection Klasse:

public class ConnectionInfo 
{ 
    public string ConnectionString { get; set; } 
    public string User { get; set; } 
} 

Jetzt in Modell haben Sie den folgenden Konstruktor:

private string _user { get; } 

public Model(ConnectionInfo connection) 
    : base(connection.ConnectionString) 
{ 
    _user = connection.User; 
} 


private void AddTimestamps() 
{ 
    var entities = ChangeTracker.Entries() 
     .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified); 

    var currentUser = _user; 
} 
Verwandte Themen