ASP.NET MVC 5-신원. 현재 ApplicationUser를 얻는 방법


237

프로젝트에 ApplicationUser이라는 속성 을 가진 기사 엔터티가 Author있습니다. 현재 기록 된 전체 개체를 얻으려면 어떻게 ApplicationUser해야합니까? 새 기사를 만드는 동안 Author속성을 Articlecurrent 로 설정해야 합니다 ApplicationUser.

이전 멤버십 메커니즘에서는 간단했지만 새로운 ID 접근 방식에서는이를 수행하는 방법을 모릅니다.

나는 이런 식으로 시도했다.

  • 신원 확장을위한 using 문 추가 : 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)'메소드를 인식하지 못하므로이 메소드를 상점 표현식으로 변환 할 수 없습니다. Source = EntityFramework

답변:


448

현재 ApplicationUser에 대해 데이터베이스를 직접 조회 할 필요는 없습니다.

이는 초보자를위한 추가 컨텍스트를 갖는 새로운 종속성을 도입하지만 사용자 데이터베이스 테이블 변경 (지난 2 년 동안 3 번)을 진행하지만 API는 일관됩니다. 예를 들어, users테이블은 이제라고 AspNetUsers신원 프레임 워크에, 여러 기본 키 필드의 이름은 더 이상 작동하는 몇 가지 답변의 코드, 그래서 계속 변화 -그대로 .

또 다른 문제는 데이터베이스에 대한 기본 OWIN 액세스가 별도의 컨텍스트를 사용하므로 별도의 SQL 액세스에서 변경하면 유효하지 않은 결과가 발생할 수 있습니다 (예 : 데이터베이스에 대한 변경 사항이 표시되지 않음). 다시 한 번 해결책은 제공된 API를 사용 하여 해결 하는 것입니다.

현재 날짜와 같이 ASP.Net ID에서 현재 사용자 개체에 액세스하는 올바른 방법은 다음과 같습니다.

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

또는 비동기 작업이있는 경우 다음과 같습니다.

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

FindById비동기식이 아닌 UserManager메소드를 사용할 수 있도록 다음 using 문이 필요합니다 ( UserManager의 확장 메소드 이므로이를 포함하지 않으면 FindByIdAsync) 만 표시 됩니다.

using Microsoft.AspNet.Identity;

컨트롤러에 전혀없는 경우 (예 : IOC 주입을 사용하는 경우) 다음에서 사용자 ID를 완전히 검색합니다.

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. 이것을 Controller의 생성자에 추가하십시오 :

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

2015 년 3 월 업데이트

참고 : 최신 Identity 프레임 워크 업데이트는 인증에 사용되는 기본 클래스 중 하나를 변경합니다. 현재 HttpContent의 Owin 컨텍스트에서 액세스 할 수 있습니다.

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

추가:

원격 데이터베이스 연결 (예 : Azure 데이터베이스에 대한 로컬 호스트 테스트)을 통해 Azure에서 EF 및 Identity Framework를 사용하는 경우 두려운 "오류 : 19-물리적 연결을 사용할 수 없습니다"라는 오류가 임의로 발생할 수 있습니다. 재 시도를 추가 할 수없는 (또는 누락 된 것으로 보이는) Identity Framework 내부에 원인이 묻혀 있으므로 프로젝트에서 .Include(x->someTable)사용자 정의를 구현해야합니다 SqlAzureExecutionStrategy.


5
@ TBA-감사합니다. 나중에 확장 방법이라는 것을 깨달았습니다. 를 사용하여 Microsoft.AspNet.Identity를 추가해야합니다. 다시 한 번 감사드립니다
Sentinel

2
Types 또는 namesapce UserStore를 찾을 수 없습니다. Microsft.AspNet.Indentity를 사용하여 추가했습니다
Wasfa

2
@Zapnologica : 새로운 질문처럼 들립니다 (게스트 제안). ApplicationUser클래스 (응용 프로그램 별)와 AspNetUsers테이블을 병렬로 확장 할 수 있으며 새 필드를 제공합니다. 다시 : 데이터베이스를 직접 누르지 마십시오! :)
Gone Coding

2
LifeH2O @ 다음 ApplicationUser는 findById 메소드에 의해 반환되는 것은 당신의 완전한 클래스, 귀하의 추가 속성. 시도하십시오.
사라지다

1
새로운 해결 방법을 기다리는 중 : P
Anup Sharma

60

내 실수는 LINQ 쿼리 내부에서 메서드를 사용해서는 안됩니다.

올바른 코드 :

using Microsoft.AspNet.Identity;


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

2
User.Identiy.GetUserId가 존재하지 않습니다. 그게 내가 맞춤형 방법입니까? 나는 User.Identity에 도착
Gerrie Pretorius

9
신경 쓰지 마라 ... "Microsoft.AspNet.Identity 사용"; 그 방법이있을 수 있습니다.
Gerrie Pretorius

4
참고로 User 개체는 컨트롤러에서만 볼 수 있습니다.
Miro J.

8
반드시 UserManager메소드를 사용 하고 데이터베이스를 직접 누르지 않아야합니까?
사라 코딩

3
@Josh Bjelovuk : API를 사용할 수있을 때 데이터베이스에 직접 도달하지 마십시오. 이는 초보자를위한 추가 컨텍스트를 갖는 새로운 종속성을 도입하지만 사용자 데이터베이스 테이블 변경 (지난 2 년 동안 3 번)을 진행하지만 API는 일관됩니다.
사라 코딩

33

그것은 답변의 의견에 있지만 아무도 이것을 실제 해결책으로 게시하지 않았습니다.

맨 위에 using 문을 추가하기 만하면됩니다.

using Microsoft.AspNet.Identity;

2
나는 그 예외로 여기에 왔고, 그것을 해결했다 using. 15k 명의 사람들이 내가 유용한 답변이라고 생각한 질문을 방문했을 때 :)
rtpHarry

2
@TrueBlueAussie는 OP 질문에 대한 직접적인 대답은 아니지만 사용법을 언급하는 것이 매우 유용한 추가 요소라고 생각합니다.
StuartQ

1
때문에 명확성을 위해, 그것의 .GetUserId()확장 방법입니다
FSCKur

11

Ellbar의 코드가 작동합니다! 사용 만 추가하면됩니다.

1 - using Microsoft.AspNet.Identity;

그리고 ... 엘바의 코드 :

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

(이 코드로 currentUser), 당신은 당신이 여분의 데이터를 원하는 경우 ... 연결된 사용자의 일반 데이터를 작동 볼 이 링크를


5
그것은 할 수있다 "작업"하지만 그것은 확실히하지 않는 것이 좋습니다 제공된 API 우회하고 당신이 여분의 데이터를 얻기 위해 추가 작업이 필요하지 않을 API를 사용했다면 데이터베이스를 직접 공격 은 이미에있을 것 같은 ApplicationUser객체
사라 코딩

나는 동의한다! 그러나 데이터베이스에 실행이 가능한 시스템이 이미 설치되어 있으므로이 문제를 해결하려면 간단한 해결책이 필요합니다. 확실히 초기 시스템에서는 객체를 적절한 클래스와 정체성에 넣을 것입니다.
Diego Borges

6

ASP.NET Identity 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
이미 다루었 다. 동일한 답변이 아직 게시되지 않았는지 확인하십시오 (또는 기존 답변에 의견 추가) :)
Gone Coding

3

현재 asp.mvc 프로젝트 템플릿은 다음과 같이 usermanager를 가져 오는 계정 컨트롤러를 만듭니다.

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());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.