Yapıcı içinde HttpContext'in boş olduğuna oldukça şaşırdığımı söylemeliyim. Eminim performans nedenlerinden dolayıdır. IPrincipalAşağıda açıklandığı gibi kullanmanın yapıcıya enjekte edilmesini sağladığını doğruladınız . Esasen kabul edilen cevapla aynı şeyi yapıyor, ancak daha arayüzey bir şekilde.
Bu soruyu bulan ve genel "Mevcut kullanıcı nasıl edinilir ?" Sorusuna cevap arayan herkes için. Userdoğrudan adresinden erişebilirsiniz Controller.User. Ancak bunu yalnızca eylem yöntemlerinin içinde yapabilirsiniz (sanırım, çünkü denetleyiciler yalnızca HttpContexts ile ve performans nedenleriyle çalışmaz).
Bununla birlikte, kurucuda buna ihtiyacınız varsa (OP'nin yaptığı gibi) veya mevcut kullanıcıya ihtiyaç duyan başka enjekte edilebilir nesneler oluşturmanız gerekiyorsa, aşağıdaki daha iyi bir yaklaşımdır:
Kullanıcı almak için IPrincipal enjekte edin
İlk tanışma IPrincipalveIIdentity
public interface IPrincipal
{
IIdentity Identity { get; }
bool IsInRole(string role);
}
public interface IIdentity
{
string AuthenticationType { get; }
bool IsAuthenticated { get; }
string Name { get; }
}
IPrincipalve IIdentitykullanıcı ve kullanıcı adını temsil eder. 'Müdür' tuhaf gelirse Wikipedia sizi rahatlatacaktır .
Önemli gerçekleştirmek için buna öyle olsun ister IHttpContextAccessor.HttpContext.User, ControllerBase.Useryoksa ControllerBase.HttpContext.Usersen mi bir olması sağlanır nesneyi almak ClaimsPrincipalhangi uygular nesneIPrincipal .
Şu Useranda ASP.NET'in kullandığı başka bir Kullanıcı türü yoktur (ancak bu, başka bir şeyin uygulayamayacağı anlamına gelmez IPrincipal).
Dolayısıyla, enjekte edilmesini istediğiniz 'mevcut kullanıcı adı'na bağımlı olan bir şeyiniz varsa, enjekte etmelisiniz IPrincipalve kesinlikle yapmamalısınız IHttpContextAccessor.
Önemli:IPrincipal Doğrudan kontrol cihazınıza veya işlem yönteminize enjekte etmek için zaman kaybetmeyin - bu anlamsızdır çünkü Userzaten orada sizin için mevcuttur.
İçinde startup.cs:
// Inject IPrincipal
services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
Daha sonra, kullanıcıya ihtiyaç duyan DI nesnenizde, sadece IPrincipalmevcut kullanıcıyı almak için enjekte edersiniz.
Buradaki en önemli şey, eğer birim testleri yapıyorsanız, bir tane göndermenize HttpContextgerek yoktur IPrincipal , sadece olabileni temsil eden bir şeyle dalga geçmeniz gerekir ClaimsPrincipal.
% 100 emin olmadığım bir ekstra önemli şey. Eğer gerçek iddiaları erişmesi gerekiyorsa dan ClaimsPrincipalsen döküm gerekir IPrincipaliçin ClaimsPrincipal. Bu sorun değil, çünkü çalışma zamanında bu türden olduğunu% 100 biliyoruz (çünkü öyle HttpContext.User). Aslında bunu yapıcıda yapmaktan hoşlanıyorum çünkü herhangi IPrincipal birinin a olacağını zaten kesin olarak biliyorum ClaimsPrincipal.
Alay ediyorsanız, doğrudan bir tane oluşturunClaimsPrincipal ve ne gerekiyorsa ona iletin IPrincipal.
Tam olarak neden arayüz IClaimsPrincipalolmadığından emin değilim. Sanırım MS ClaimsPrincipal, bunun bir arabirimi garanti etmeyen özel bir 'koleksiyon' olduğuna karar verdi .