48

(VS2013 RTW、ASP.NET MVC5 を使用)

ASP.NET ID を使用するときに、ApplicationUser クラス (およびテーブル) にプロパティを追加する方法に関する多くのドキュメントを見てきました。しかし、外部キーを介して ApplicationUser テーブルにマップされるコンテンツを含む別のテーブルを作成する方法に関するドキュメントは見たことがありません。

独自の Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext の派生に成功し、独自の "UserPreferences" テーブルが SQL Server データベースのさまざまな "AspNet*" テーブルと調和して共存できるようになりました。しかし、「UserPreferences」テーブルに新しい行を書き込むために現在のユーザーの ID を取得する最善の方法については明確ではありません。プロジェクトは ASP.NET MVC ですが、Web API コントローラーを追加しました (そして内部で作業しています)。

私は実用的な解決策を持っています:

            var uman = new Microsoft.AspNet.Identity.UserManager<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new App1.Data.App1DbContext()));

            var uident = User.Identity;

            var userobject = uman.FindByNameAsync(uident.Name);

            var userid = userobject.Result.Id;
            // (Perform new row creation including the userid we just looked up

AspNetUsers テーブル (Identity フレームワークによって定義されている) は、次のフィールドで構成されていると考えてください。

-id (PK, nvarchar(128) - seems to contain a GUID, not sure why not an autoincrement integer, but I assume there are reasons for this)
-Username (nvarchar(max))
-PasswordHash (nvarchar(max))
-SecurityStamp (nvarchar(max))

id フィールド (ユーザー名ではない) は、このテーブルで参照する正しいフィールドだと思います。(ユーザーが自分のユーザー名を変更すると、他の誰かが他のユーザーのユーザー名を引き継ぐ可能性があると考えていました。そのため、両方のフィールドが存在する可能性があります。)したがって、現在のユーザーの ID を取得して、上記のコードが行う「UserPreferences」テーブル。しかし、このルックアップを行わなければならないのは効率が悪いようです。

重要な点は、System.Web.Mvc.Controller のコンテキストでは、次のことができるということです。

User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity)

しかし、System.Web.Http.ApiController (Web API) のコンテキストでは、そのメソッドが存在しないため (User.Identity のランタイム タイプ: System.Security.Claims.ClaimsIdentity)、代わりに依存する必要があるため、できません。 :

User.Identity.Name

追加のルックアップを実行して、名前を ID に変換します。これを改善する方法について何か提案はありますか? ユーザーデータを別のテーブルに正しい方法で書き込むタスクに取り組んでいますか?

4

5 に答える 5

59

ID 1.0 RTW パッケージの同じ拡張メソッドによって、MVC コントローラーと Web API コントローラーの両方でユーザー ID を取得できるはずです。

ID パッケージの拡張機能は次のとおりです。

namespace Microsoft.AspNet.Identity
{
    public static class IdentityExtensions
    {
        public static string FindFirstValue(this ClaimsIdentity identity, string claimType);
        public static string GetUserId(this IIdentity identity);
        public static string GetUserName(this IIdentity identity);
    }
}

IIdentity は、すべての ID タイプの基本インターフェイスです。拡張メソッドを表示するには、「using Microsoft.AspNet.Identity」を追加する必要がある場合があります。

ところで: ユーザー用の外部テーブルの追加に関して、ApplicationUser を使用せず、ナビゲーション プロパティを UserPreference に追加して、EF がそれらの関係を処理できるようにしないのはなぜですか? その方が簡単です。

于 2013-10-21T22:57:00.337 に答える
46
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID));

ClaimTypes.NameIdentifier関数のクレームですUser.Identity.GetUserId()

于 2014-10-19T18:11:56.877 に答える
3

最良の回答の簡単な説明:

  1. Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1
  2. var userId = User.Identity.GetUserId();
于 2017-09-03T02:46:59.787 に答える
0

@Mastenkaの回答を試してみましたが、何も得られませんでした。ClaimsIdentity を確認したところ、クレーム タイプ "UserName" があったため、"UserName" を ClaimsType として使用してユーザー名を取得します。誰かがそれについてもっと情報を提供してくれることを願っています。「ClaimTypes.NameIdentifier」が効果がないのは奇妙に見えます。(ApiController、ASP MVC API)

var userName = ((ClaimsIdentity)RequestContext.Principal.Identity).Claims.FirstOrDefault(cl => cl.Type == "UserName")?.Value;
于 2019-08-06T14:10:01.420 に答える