मुझे कहना है कि मुझे काफी आश्चर्य हुआ कि कंस्ट्रक्टर के अंदर HttpContext शून्य है। मुझे यकीन है कि यह प्रदर्शन कारणों से है। पुष्टि की है कि IPrincipalनीचे वर्णित के रूप में उपयोग करने से यह कंस्ट्रक्टर में अंतःक्षिप्त हो जाता है। यह अनिवार्य रूप से स्वीकार किए जाते हैं उत्तर के रूप में ही कर रहे हैं, लेकिन एक अधिक स्पष्ट तरीके से।
किसी के लिए भी यह सवाल जेनेरिक के जवाब की तलाश में है "वर्तमान उपयोगकर्ता कैसे प्राप्त करें?" आप बस Userसे सीधे पहुँच सकते हैं Controller.User। लेकिन आप इसे केवल एक्शन विधियों के अंदर ही कर सकते हैं (मेरा मानना है कि नियंत्रक केवल HttpContexts और प्रदर्शन कारणों से नहीं चलते हैं)।
हालाँकि - यदि आपको कंस्ट्रक्टर में इसकी आवश्यकता है (जैसा कि ओपी ने किया था) या अन्य इंजेक्टेबल ऑब्जेक्ट बनाने की आवश्यकता है जो वर्तमान उपयोगकर्ता की आवश्यकता है तो नीचे एक बेहतर तरीका है:
उपयोगकर्ता प्राप्त करने के लिए IPrincipal इंजेक्षन
पहले मिलते हैं IPrincipalऔरIIdentity
public interface IPrincipal
{
IIdentity Identity { get; }
bool IsInRole(string role);
}
public interface IIdentity
{
string AuthenticationType { get; }
bool IsAuthenticated { get; }
string Name { get; }
}
IPrincipalऔर IIdentityउपयोगकर्ता और उपयोगकर्ता नाम का प्रतिनिधित्व करता है। अगर al प्रिंसिपल ’अजीब लगे तो विकिपीडिया आपको सुकून देगा ।
यह महसूस करना महत्वपूर्ण है कि क्या आप इसे प्राप्त करते हैं IHttpContextAccessor.HttpContext.User, ControllerBase.Userया ControllerBase.HttpContext.Userआपको एक ऐसी वस्तु मिल रही है जिसकी गारंटी एक ऐसी ClaimsPrincipalवस्तु है जो लागू होती हैIPrincipal ।
कोई अन्य प्रकार का उपयोगकर्ता नहीं है जो ASP.NET Userअभी उपयोग करता है , (लेकिन ऐसा नहीं है कि कुछ और कहें जो लागू नहीं हो सका IPrincipal)।
इसलिए यदि आपके पास कोई ऐसी चीज है जिस पर 'वर्तमान उपयोगकर्ता नाम' की निर्भरता है जिसे आप इंजेक्ट करना चाहते हैं तो आपको इंजेक्शन लगाना चाहिए IPrincipalऔर निश्चित रूप से नहीं IHttpContextAccessor।
महत्वपूर्ण:IPrincipal सीधे अपने नियंत्रक, या एक्शन विधि पर इंजेक्शन लगाने में समय बर्बाद न करें - यह तब से बेकार है जब Userसे आप पहले से ही वहां उपलब्ध हैं।
इन startup.cs:
// Inject IPrincipal
services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
फिर आपके DI ऑब्जेक्ट में उस उपयोगकर्ता की आवश्यकता है जिसे आप IPrincipalवर्तमान उपयोगकर्ता प्राप्त करने के लिए इंजेक्ट करते हैं।
यहां सबसे महत्वपूर्ण बात यह है कि यदि आप यूनिट टेस्ट कर रहे हैं तो आपको भेजने की आवश्यकता नहीं है HttpContext, लेकिन केवल कुछ का मजाक उड़ाने की जरूरत है जो प्रतिनिधित्व करता है IPrincipal जो अभी हो सकता है ClaimsPrincipal ।
एक अतिरिक्त महत्वपूर्ण बात जो मैं 100% सुनिश्चित नहीं हूं। यदि आपको वास्तविक दावों तक पहुंचने की आवश्यकता है, तो आपको ClaimsPrincipalकास्ट IPrincipalकरने की आवश्यकता है ClaimsPrincipal। यह ठीक है क्योंकि हम 100% जानते हैं कि रनटाइम में यह उस प्रकार का है (क्योंकि यही HttpContext.Userहै)। मैं वास्तव में कंस्ट्रक्टर में ऐसा करना पसंद करता हूं क्योंकि मुझे पहले से ही पता है कि कोई भी IPrincipal होगा ClaimsPrincipal।
यदि आप मॉकिंग कर रहे हैं, तो बस एक ClaimsPrincipalसीधा बनाएं और जो भी लेता है उसे पास करें IPrincipal।
वास्तव में, IClaimsPrincipalमुझे यकीन नहीं है के लिए कोई इंटरफ़ेस नहीं है। मुझे लगता है कि एमएस ने फैसला किया कि ClaimsPrincipalसिर्फ एक विशेष 'संग्रह' था जो एक इंटरफ़ेस को वारंट नहीं करता था।