ASP.NET MVC 5 - Kimlik. Geçerli ApplicationUser nasıl edinilir


237

Projemde şu ApplicationUsermülke sahip bir Makale varlığı var Author. Günlüğe kaydedilmiş olan tam nesneyi nasıl alabilirim ApplicationUser? Yeni bir makale oluştururken, Authorözelliği Articlegeçerli olarak ayarlamalıyım ApplicationUser.

Eski Üyelik mekanizmasında basitti, ancak yeni Kimlik yaklaşımında bunu nasıl yapacağımı bilmiyorum.

Bu şekilde yapmaya çalıştım:

  • Kimlik uzantıları için deyim kullanarak ekleme: using Microsoft.AspNet.Identity;
  • Sonra şu anki kullanıcıyı almaya çalışıyorum: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

Ama şu istisnayı alıyorum:

LINQ to Entities, 'System.String GetUserId (System.Security.Principal.IIdentity)' yöntemini tanımıyor ve bu yöntem bir mağaza ifadesine dönüştürülemiyor. Kaynak = EntityFramework

Yanıtlar:


448

Geçerli ApplicationUser için veritabanını doğrudan sorgulamanız gerekmez.

Bu, yeni başlayanlar için ekstra bir bağlama sahip olmak için yeni bir bağımlılık getiriyor, ancak ileride kullanıcı veritabanı tabloları değişiyor (son 2 yılda 3 kez), ancak API tutarlı. Örneğin, userstablo şimdi AspNetUsersIdentity Framework içinde çağrıldı ve birkaç birincil anahtar alanının adları değişmeye devam etti, bu nedenle birkaç cevaptaki kod artık olduğu gibi çalışmayacak .

Başka bir sorun, veritabanının altında yatan OWIN erişiminin ayrı bir bağlam kullanmasıdır, bu nedenle ayrı SQL erişimindeki değişiklikler geçersiz sonuçlar üretebilir (örneğin veritabanında yapılan değişiklikleri görmemek). Yine çözüm, verilen API ile çalışmak ve çözüm bulmaya çalışmak değil.

ASP.Net kimliğindeki geçerli kullanıcı nesnesine (bu tarihte olduğu gibi) erişmenin doğru yolu:

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

veya zaman uyumsuz bir işleminiz varsa şuna benzer:

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

FindByIdasync olmayan UserManageryöntemlerin kullanılabilmesi için aşağıdaki kullanım ifadesine sahip olmanızı gerektirir (bunlar UserManager için uzantı yöntemleridir , bu yüzden bunu eklemezseniz yalnızca göreceksiniz FindByIdAsync):

using Microsoft.AspNet.Identity;

Hiç bir denetleyicide değilseniz (örn. IOC enjeksiyonu kullanıyorsanız), kullanıcı kimliği aşağıdakilerden tam olarak alınır:

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

Standart Hesap denetleyicisinde değilseniz, denetleyicinize aşağıdakileri (örnek olarak) eklemeniz gerekir:

1. Bu iki özelliği ekleyin:

    /// <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. Bunu Denetleyicinin yapıcısına ekleyin:

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

Mart 2015 Güncellemesi

Not: Kimlik çerçevesine yapılan en son güncelleme, kimlik doğrulama için kullanılan temel sınıflardan birini değiştirir. Artık ona mevcut HttpContent'in Owin Bağlamından erişebilirsiniz.

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

Zeyilname:

EF ve Identity Framework'ü Azure ile kullanırken, uzak bir veritabanı bağlantısı üzerinden (örneğin, Azure veritabanına yerel ana bilgisayar testi), korkunç "hata: 19 - Fiziksel bağlantı kullanılamaz" seçeneğini rastgele vurabilirsiniz. Neden yeniden deneme ekleyemediğiniz (veya eksik görünen .Include(x->someTable)) Identity Framework içine gömüldüğünden SqlAzureExecutionStrategy, projenize bir özel uygulama uygulamanız gerekir .


5
@TBA - teşekkürler, daha sonra bunun bir uzatma yöntemi olduğunu anladım. Kullanarak Microsoft.AspNet.Identity eklemeniz gerekir. tekrar teşekkürler
Sentinel

2
Type veya namesapce UserStore bulunamadı. Microsft.AspNet.Indentity
Wasfa

2
@Zapnologica: Bu yeni bir soruya benziyor (göndermenizi öneririz). ApplicationUserSınıfı (uygulamaya özel) ve AspNetUserstabloyu paralel olarak genişletebilirsiniz ve yeni alanlar sağlarlar. Tekrar: Veritabanına doğrudan vurmayın! :)
Gitti Kodlama

2
LifeH2O @: ApplicationUser FindById tarafından döndürülen olan sizin ile tam sınıf, senin ekstra özellikler. Lütfen dene.
Gitti Kodlama

1
Yeni Geçici
Çözümünüzü

60

Benim hatam, bir LINQ sorgu içinde bir yöntem kullanmamalıydım.

Doğru kod:

using Microsoft.AspNet.Identity;


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

2
User.Identiy.GetUserId benim için mevcut değil. bu ben özel yöntem mi? Ben sadece User.Identity
Gerrie Pretorius

9
Boş ver ... "Microsoft.AspNet.Identity kullanarak;" bu yöntemin orada olması için.
Gerrie Pretorius

4
Yalnızca bir not, Kullanıcı nesnesi yalnızca Denetleyiciler'de görünür.
Miro

8
Elbette UserManageryöntemleri kullanmalı ve veritabanına doğrudan vurmamalısınız?
Gitti Kodlama

3
@Josh Bjelovuk: Bir API kullanılabilir olduğunda asla doğrudan veritabanına vurmayın. Bu, yeni başlayanlar için ekstra bir bağlama sahip olmak için yeni bir bağımlılık getiriyor, ancak ileride kullanıcı veritabanı tabloları değişiyor (son 2 yılda 3 kez), ancak API tutarlı.
Gone Coding

33

Bu cevapların yorumlarında ama kimse bunu asıl çözüm olarak yayınladı.

Üst kısma bir using ifadesi eklemeniz yeterlidir:

using Microsoft.AspNet.Identity;

2
Bu istisna dışında buraya geldim, çözdüm using. 15k insanın bu yararlı bir cevap olduğunu düşündüm sorusunu ziyaret etmiş olarak görmek :)
rtpHarry

2
@TrueBlueAussie, OPs sorusuna doğrudan bir cevap olmamasına rağmen, kullanımdan bahsetmenin çok yararlı bir ek olduğunu hissediyorum.
StuartQ

1
Anlaşılır olması için, bunun .GetUserId()bir uzatma yöntemi olması
FSCKur

11

Ellbar'ın kodu çalışıyor! Yalnızca şunu kullanarak eklemeniz gerekir.

1 - using Microsoft.AspNet.Identity;

Ve ... Ellbar'ın kodu:

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

Bu kodla (in currentUser), fazladan veri istiyorsanız bağlı kullanıcının genel verilerini kullanırsınız ... bu bağlantıya bakın


5
"Çalışabilir", ancak sağlanan API'yi atlamanız ve doğrudan veritabanına vurmanız kesinlikle önerilmez . API'yi kullandıysanız , ApplicationUsernesnede olduğu gibi
Gone Coding

Katılıyorum! Ancak, veritabanına bir çalışma ile bugün zaten bir sistem vardı çünkü bu şekilde başvurdu ve bu sorunu çözmek için basit bir çözüm gerekiyor! Elbette, erken bir sistemde, nesneleri uygun sınıflarına ve kimliklerine koyardım.
Diego Borges

6

ASP.NET Identity 3.0.0'dan itibaren,

//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 için, WebApplication şablon iskelesinde ManageController'ın EnableTwoFactorAuthentication yönteminin içine bakın, orada yapılıyor:

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

Yanıt, Microsoft'un önerdiği gibi:

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

ApplicationUser sınıfında tanımladığınız tüm ek özelliklere sahip olacaktır.


5
Zaten kapatılmış. Lütfen aynı cevabın henüz gönderilmediğinden emin olun (veya mevcut bir cevaba yorum ekleyin) :)
Gone Coding

3

Şu anda asp.mvc proje şablonu, kullanıcı yönetimini bu şekilde alan bir hesap denetleyicisi oluşturur:

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

Aşağıdakiler benim için çalışıyor:

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

0

Kod Parçasını Takip ederek Uygulama Kullanıcısını başarıyla alabildim

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

0

Birinin Identitykullanıcılarla çalışması durumunda web forms, bunu yaparak çalıştım:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.