1. ホーム
  2. c#

[解決済み] [Solved] ASP.NET MVC 5 - Identity. 現在のApplicationUserを取得する方法

2022-04-01 05:33:55

質問

私のプロジェクトには、Article エンティティがあり、それには ApplicationUser という名前のプロパティがあります。 Author . どうすれば現在ログに記録されている ApplicationUser ? 新しい記事を作成するとき、私は Author プロパティは Article を現在の ApplicationUser .

古いMembershipメカニズムでは簡単だったが、新しいIdentityアプローチでは、これをどのように行うか分からない。

このようにやってみました。

  • 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)' メソッドを認識せず、このメソッドはストア式に変換できません。 ソース=EntityFramework

解決方法は?

現在の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 には、以下のようなusingステートメントが必要で、非同期の UserManager メソッドが利用可能です(それらは 拡張メソッド が表示されるだけなので、これを含めないと FindByIdAsync ):

using Microsoft.AspNet.Identity;

もし、コントローラに全く入っていない場合(例えばIOCインジェクションを使っている場合)、ユーザーIDはfull fromで取得されます。

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

もし、標準の Account コントローラーでない場合は、以下のように (例として) コントローラーに追加する必要があります。

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 framework の最新のアップデートでは、認証に使用される基礎クラスの 1 つが変更されています。 現在のHttpContentのOwin Contextからアクセスできるようになりました。

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

追記

EF と Identity Framework を Azure で使用する場合、リモートデータベース接続 (ローカルホストから Azure データベースへのテストなど) で、ランダムに恐ろしい「エラー」が発生することがあります。19 - 物理接続は使用できません" というエラーが発生することがあります。原因はIdentity Frameworkの中に埋もれているため、再試行を追加することはできません(または、不足していると思われる .Include(x->someTable) を実装する必要があります。 SqlAzureExecutionStrategy をプロジェクトに組み込んでください。