ASP.NET MVC 5 - पहचान। वर्तमान ApplicationUser कैसे प्राप्त करें


237

मेरी परियोजना में एक अनुच्छेद इकाई है, जिसके पास ApplicationUserसंपत्ति है Author। मैं वर्तमान में लॉग इन की पूरी वस्तु कैसे प्राप्त कर सकता हूं ApplicationUser? एक नया लेख बनाते समय, मुझे Authorसंपत्ति Articleको वर्तमान में सेट करना होगा ApplicationUser

पुराने सदस्यता तंत्र में यह सरल था, लेकिन नए आइडेंटिटी दृष्टिकोण में मुझे नहीं पता कि यह कैसे करना है।

मैंने इसे इस तरह से करने की कोशिश की:

  • पहचान एक्सटेंशन के लिए स्टेटमेंट का उपयोग करके जोड़ें: using Microsoft.AspNet.Identity;
  • फिर मैं वर्तमान उपयोगकर्ता प्राप्त करने का प्रयास करता हूं: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

लेकिन मुझे निम्नलिखित अपवाद मिलते हैं:

LINQ to Entities विधि 'System.String GetUserId (System.Security.Principal.IIdentity)' विधि को नहीं पहचानता है, और इस पद्धति का स्टोर अभिव्यक्ति में अनुवाद नहीं किया जा सकता है। स्रोत = EntityFramework

जवाबों:


448

आपको वर्तमान ApplicationUser के लिए सीधे डेटाबेस को क्वेरी करने की आवश्यकता नहीं होनी चाहिए।

यह शुरुआत के लिए एक अतिरिक्त संदर्भ होने की एक नई निर्भरता का परिचय देता है, लेकिन आगे जाकर उपयोगकर्ता डेटाबेस तालिकाओं में परिवर्तन होता है (पिछले 2 वर्षों में 3 बार) लेकिन एपीआई सुसंगत है। उदाहरण के लिए usersतालिका को अब AspNetUsersआइडेंटिटी फ्रेमवर्क में कहा जाता है, और कई प्राथमिक कुंजी फ़ील्ड के नाम बदलते रहते हैं, इसलिए कई उत्तरों में कोड अब के रूप में काम नहीं करेगा ।

एक अन्य समस्या यह है कि डेटाबेस में अंतर्निहित OWIN एक्सेस एक अलग संदर्भ का उपयोग करेगा, इसलिए अलग SQL एक्सेस से परिवर्तन अमान्य परिणाम उत्पन्न कर सकते हैं (उदाहरण के लिए डेटाबेस में किए गए परिवर्तन नहीं देख रहे हैं)। फिर से समाधान आपूर्ति की गई एपीआई के साथ काम करना है और इसके आसपास काम करने की कोशिश न करें ।

ASP.Net पहचान (वर्तमान तिथि के अनुसार) में वर्तमान उपयोगकर्ता ऑब्जेक्ट तक पहुंचने का सही तरीका है:

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

या, यदि आपके पास एक async कार्रवाई है, तो कुछ इस तरह है:

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

FindByIdआवश्यकता है कि आपको निम्नलिखित कथन का उपयोग करना चाहिए ताकि गैर-एस्किंस UserManagerविधियाँ उपलब्ध हों (वे UserManager के लिए विस्तार विधियाँ हैं , इसलिए यदि आप इसे शामिल नहीं करते हैं तो आप केवल देखेंगे FindByIdAsync):

using Microsoft.AspNet.Identity;

यदि आप किसी कंट्रोलर में नहीं हैं (जैसे आप आईओसी इंजेक्शन का उपयोग कर रहे हैं), तो उपयोगकर्ता आईडी को इसमें से पूरी तरह से लिया गया है:

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

यदि आप मानक खाता नियंत्रक में नहीं हैं, तो आपको अपने नियंत्रक में निम्नलिखित (उदाहरण के रूप में) जोड़ने की आवश्यकता होगी:

1. इन दोनों गुणों को जोड़ें:

    /// <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. नियंत्रक के निर्माता में इसे जोड़ें:

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

मार्च 2015 को अपडेट करें

नोट: पहचान फ्रेमवर्क के लिए सबसे हालिया अपडेट प्रमाणीकरण के लिए उपयोग किए गए अंतर्निहित वर्गों में से एक को बदलता है। अब आप इसे मौजूदा HttpContent के ओवेन कॉनटेक्स्ट से एक्सेस कर सकते हैं।

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

परिशिष्ट:

दूरस्थ डेटाबेस कनेक्शन पर Azure के साथ EF और आइडेंटिटी फ्रेमवर्क का उपयोग करते समय, (Azure डेटाबेस में स्थानीय होस्ट परीक्षण जैसे), आप बेतरतीब ढंग से खतरनाक "त्रुटि: 19 - शारीरिक कनेक्शन उपयोग करने योग्य नहीं है" को हिट कर सकते हैं। जैसा कि कारण पहचान फ्रेमवर्क के अंदर दफन है, जहां आप रिट्रीस नहीं जोड़ सकते हैं (या जो एक लापता प्रतीत होता है .Include(x->someTable)), आपको SqlAzureExecutionStrategyअपनी परियोजना में एक कस्टम लागू करने की आवश्यकता है ।


5
@ टीबीए - धन्यवाद, मुझे एहसास हुआ कि बाद में यह एक विस्तार विधि है। Microsoft.AspNet.Identity का उपयोग करके जोड़ना होगा। एक बार फिर धन्यवाद
प्रहरी

2
टाइप या नेमपेस UserStore नहीं पाया जा सका। मैंने माइक्रोसॉफ्ट.स्पेनेट का उपयोग करके जोड़ा।
भारतीयता

2
@Zapnologica: यह एक नए प्रश्न जैसा लगता है (सुझाव दें कि आप इसे पोस्ट करें)। आप समानांतर में ApplicationUserवर्ग (आवेदन विशिष्ट) और AspNetUsersतालिका का विस्तार कर सकते हैं और वे कोई भी नया क्षेत्र प्रदान करेंगे। फिर से: सीधे डेटाबेस को मत मारो! :)
कोडिंग किया गया

2
@ LifeH2O: FindById द्वारा दिया गया ApplicationUser आपकी कक्षा है, जो आपके अतिरिक्त गुणों के साथ पूरी होती है । कृपया इसे आजमाएँ।
कोडिंग किया

1
आपके नए समाधान के लिए प्रतीक्षा कर रहा है: पी
अनूप शर्मा

60

मेरी गलती, मुझे LINQ क्वेरी के अंदर एक विधि का उपयोग नहीं करना चाहिए था।

सही कोड:

using Microsoft.AspNet.Identity;


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

2
मेरे लिए उपयोगकर्ता ।dentiy.GetUserId मौजूद नहीं है। कि मैं कस्टम विधि है? मैं केवल User.Identity
Gerrie Pretorius

9
कोई बात नहीं ... आपको "Microsoft.AspNet.Identity का उपयोग करना" चाहिए उस विधि के लिए वहाँ होना चाहिए।
गैरी प्रिटोरियस

4
केवल एक नोट, उपयोगकर्ता ऑब्जेक्ट केवल नियंत्रकों में दिखाई देता है।
मिरो जे।

8
निश्चित रूप से आपको UserManagerतरीकों का उपयोग करना चाहिए और डेटाबेस को सीधे नहीं मारना चाहिए ?
कोडिंग हुआ

3
@ जोश बोजेलोवुक: एपीआई उपलब्ध होने पर कभी भी सीधे डेटाबेस को हिट न करें। यह शुरुआत के लिए एक अतिरिक्त संदर्भ होने की एक नई निर्भरता का परिचय देता है, लेकिन आगे जाकर उपयोगकर्ता डेटाबेस तालिकाओं में परिवर्तन होता है (पिछले 2 वर्षों में 3 बार) लेकिन एपीआई सुसंगत है।
चला गया

33

इसके जवाब की टिप्पणियों में लेकिन किसी ने भी इसे वास्तविक समाधान के रूप में पोस्ट नहीं किया है।

आपको बस शीर्ष पर एक उपयोग कथन जोड़ना होगा:

using Microsoft.AspNet.Identity;

2
मैं उस अपवाद के साथ यहां आया, मैंने इसे उसी के साथ हल किया using। यह देख कर कि १५ k लोगों ने इस सवाल का जवाब दिया है कि मुझे लगा कि यह एक उपयोगी उत्तर है :)
rtpHarry

2
@TrueBlueAussie, ओपीएस सवाल का सीधा जवाब नहीं होने के बावजूद, मुझे लगता है कि उपयोग का उल्लेख करना एक बहुत ही उपयोगी जोड़ है।
स्टुअर्टक्यू

1
स्पष्टता के लिए, यह इसलिए .GetUserId()है क्योंकि एक विस्तार विधि है
FSCKur

11

एलबर का कोड काम करता है! आपको केवल उपयोग करने की आवश्यकता है

1 - using Microsoft.AspNet.Identity;

और ... एलबर का कोड:

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

इस कोड (इन currentUser) के साथ, आप कनेक्ट किए गए उपयोगकर्ता के सामान्य डेटा को काम करते हैं, यदि आप अतिरिक्त डेटा चाहते हैं ... इस लिंक को देखें


5
यह "काम" हो सकता है, लेकिन यह निश्चित रूप से आपूर्ति की गई एपीआई को बायपास करने और डेटाबेस को सीधे हिट करने की अनुशंसा नहीं करता है यदि आपने एपीआई का उपयोग किया है तो आपको अतिरिक्त डेटा प्राप्त करने के लिए अतिरिक्त काम की आवश्यकता नहीं होगी क्योंकि यह पहले से ही ApplicationUserऑब्जेक्ट में होगा
कोडिंग हो गया।

मैं सहमत हूँ! हालाँकि, इस तरह से सहारा लिया गया क्योंकि मेरे पास पहले से ही एक सिस्टम था आज डेटाबेस में एक रन के साथ और मुझे इस मुद्दे को हल करने के लिए एक सरल समाधान की आवश्यकता है! निश्चित रूप से, एक प्रारंभिक प्रणाली में, मैं वस्तुओं को उनके उचित वर्गों और पहचानों में रखूंगा।
डिएगो बोर्गेस

6

ASP.NET आइडेंटिटी 3.0.0 के रूप में, इसे फिर से चालू कर दिया गया है

//returns the userid claim value if present, otherwise returns null
User.GetUserId();

6
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;

3

MVC 5 के लिए WebApplication टेम्पलेट पाड़ में ManageController के EnableTwoFactorAuthentication विधि के अंदर देखें, इसे वहां किया जा रहा है:

        [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");
        }

Microsoft द्वारा सुझाए गए अनुसार उत्तर ठीक है:

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

इसमें आपके द्वारा ApplicationUser वर्ग में परिभाषित सभी अतिरिक्त गुण होंगे।


5
पहले से ही कवर किया गया। कृपया जांचें कि एक समान उत्तर पहले से ही पोस्ट नहीं किया गया है (या किसी मौजूदा उत्तर के लिए एक टिप्पणी जोड़ें) :)
G21 Coding

3

अभी asp.mvc प्रोजेक्ट टेम्प्लेट एक खाता नियंत्रक बनाता है जो इस तरह से प्रवेश करता है:

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

निम्नलिखित मेरे लिए काम करता है:

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

0

कोड ऑफ पीस के द्वारा एप्लिकेशन उपयोगकर्ता प्राप्त करने के लिए मैं सफलतापूर्वक उपलब्ध था

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

0

यदि कोई व्यक्ति Identityउपयोगकर्ताओं के साथ काम कर web formsरहा है, तो मुझे ऐसा करके काम करना पड़ा:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.