web-dev-qa-db-ja.com

ASP.NET MVC 5 - アイデンティティ。現在のApplicationUserを取得する方法

私のプロジェクトにはApplicationUserというAuthorプロパティを持つArticleエンティティがあります。現在記録されているApplicationUserの完全なオブジェクトを取得するにはどうすればいいですか?新しい記事を作成している間、AuthorArticleプロパティを現在の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)'メソッドを認識しないため、このメソッドをストア式に変換することはできません。ソース= EntityFramework

223
Ellbar

現在のApplicationUserについてデータベースに直接問い合わせる必要はありません。

これは、初心者向けに追加のコンテキストを持つという新たな依存関係をもたらしますが、今後はユーザーデータベーステーブルが変更されます(過去2年間で3回)が、APIは一貫しています。たとえば、Identity Frameworkでは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ではextension methodsです。これを含めない場合は、FindByIdAsyncのみが表示されます)。

using Microsoft.AspNet.Identity;

あなたがまったくコントローラーにいない場合(例えばIOC injectionを使用している場合)、ユーザー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.これをControllerのコンストラクタに追加します。

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

2015年3月更新

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

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

補遺:

AzureでEFおよびIdentity Frameworkを使用している場合、リモートデータベース接続(Azureデータベースに対するローカルホストテストなど)を使用すると、「エラー:19 - 物理接続が使用できません」という恐ろしいエラーがランダムに発生します。再試行を追加することができない(または不足している.Include(x->someTable)のように見える)Identity Frameworkの内部に原因が埋まっているので、プロジェクトにカスタムのSqlAzureExecutionStrategyを実装する必要があります。

427
Gone Coding

私の間違い、私はLINQクエリの中でメソッドを使うべきではありませんでした。

正しいコード:

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

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

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

using Microsoft.AspNet.Identity;
31
rtpHarry

Ellbarのコードは機能します!あなただけを使用して追加する必要があります。

1 - using Microsoft.AspNet.Identity;

そして... Ellbarのコード:

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

このコード(currentUser内)を使えば、接続ユーザーの一般データを扱うことになります。追加のデータが必要な場合は... このリンクを参照 /

10
Diego Borges

ASP.NET Identity 3.0.0以降、これはにリファクタリングされました。

//returns the userid claim value if present, otherwise returns null
User.GetUserId();
6
Seth IK
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;
5
Majid joghataey

今のところasp.mvcプロジェクトテンプレートは、このようにユーザーマネージャを取得するアカウントコントローラを作成します。

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

以下は私のために働きます:

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

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クラスで定義したすべての追加プロパティがあります。

2
Paceman

誰かがweb formsIdentityユーザーと協力している場合、私はそうすることによってそれをうまく動かしました:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());
0
Jamshaid Kamran

コードをフォローすることでアプリケーションユーザを取得することに成功しました

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