ASP.NET MVC 5-ID。現在のApplicationUserを取得する方法


237

プロジェクトにArticle ApplicationUserという名前のプロパティを持つArticleエンティティがありますAuthor。現在ログに記録されているオブジェクト全体を取得するにはどうすればよいApplicationUserですか?新しい記事を作成するときに、AuthorプロパティをArticlecurrent に設定する必要がありますApplicationUser

以前のメンバーシップメカニズムではそれは単純でしたが、新しいアイデンティティアプローチでは、これを行う方法がわかりません。

私はこのようにしてみました:

  • Identity拡張機能の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テーブルがAspNetUsersIdentity Frameworkで呼び出され、いくつかの主キーフィールドの名前が変更され続けるため、いくつかの回答のコードはそのままでは機能なくなります。

別の問題は、データベースへの基になる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.次の2つのプロパティを追加します。

    /// <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年3月の更新

注:Identityフレームワークの最新の更新により、認証に使用される基になるクラスの1つが変更されます。これで、現在のHttpContentのOwinコンテキストからアクセスできます。

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

補遺:

AzureでEFおよびIdentity Frameworkを使用する場合、リモートデータベース接続(Azureデータベースへのローカルホストテストなど)を介して、恐ろしい「エラー:19-物理接続は使用できません」にランダムにヒットする可能性があります。原因は、再試行を追加できないIdentity Framework(または欠落しているように見えるもの.Include(x->someTable))に隠れているため、SqlAzureExecutionStrategyプロジェクトにカスタムを実装する必要があります。


5
@TBA-おかげで、私は後でそれが拡張メソッドであることに気付きました。を使用してMicrosoft.AspNet.Identityを追加する必要があります。再度ありがとう
Sentinel 2014年

2
タイプまたは名前空間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 2014年

4
注意点として、ユーザーオブジェクトはコントローラーでのみ表示されます。
ミロJ.

8
確かに、UserManagerメソッドを使用し、データベースに直接アクセスしないでください。
コーディング終了

3
@Josh Bjelovuk:APIが利用可能な場合は、データベースに直接アクセスしないでください。これは、初心者のための追加のコンテキストを持つという新しい依存関係を導入しますが、ユーザーデータベーステーブルの変更は(過去2年間で3回)変化しますが、APIは一貫しています。
コーディングを終了

33

それは回答のコメントにありますが、実際の解決策としてこれを投稿した人はいません。

上部にusingステートメントを追加するだけです。

using Microsoft.AspNet.Identity;

2
私はその例外を除いてここに来ました、それでそれを解決しましたusing。15k人がこの質問にアクセスしたので、私はそれが役に立つ答えだと思いました:)
rtpHarry 2014年

2
@TrueBlueAussieは、OPの質問に対する直接の回答ではありませんが、使用について言及することは非常に便利な追加機能だと思います。
StuartQ 2015年

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
それは「仕事」かもしれないが、それは確かにされていないお勧めします提供するAPIバイパスにし、あなたが余分なデータを取得するために余分な作業を必要としないAPIを使用しなかった場合は、直接データベースを打つ、それは既にになるようApplicationUserオブジェクトを
ゴーンコーディング

同意する!しかし、私はすでにデータベースを実行しているシステムをすでに配備していて、この問題を解決する簡単な解決策が必要なので、この方法に頼りました!確かに、初期のシステムでは、オブジェクトを適切なクラスとIDに入れていました。
ディエゴボルヘス

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プロジェクトテンプレートは、この方法でユーザーマネージャーを取得するアカウントコントローラーを作成します。

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.