質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

9285閲覧

.net Identity に登録した自分の情報(追加分)を 画面に表示したい

pcb

総合スコア7

Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

1グッド

1クリップ

投稿2017/04/06 07:44

編集2017/04/06 07:51

###前提
Visual studio 2013 for webで開発をしております。
VB/C#いずれでもかまいません(実際にはVBで開発しています)。

新しくMVC5アプリケーションをテンプレートから生成したあと、
以下の拡張を行いました:

/models/ientityModel.vb

....(imports省略).... ' ApplicationUser クラスにプロパティを追加することでユーザーのプロファイル データを追加できます。詳細については、http://go.microsoft.com/fwlink/?LinkID=317594 を参照してください。 Public Class ApplicationUser Inherits IdentityUser ''' <summary> ''' 登録連番 ''' </summary> <Required> <Display(Name:="登録連番")> <DatabaseGenerated(DatabaseGeneratedOption.Identity)> <Column("ID_NUM", Order:=0)> Public Property Id_Num As Integer Public Async Function GenerateUserIdentityAsync(manager As UserManager(Of ApplicationUser)) As Task(Of ClaimsIdentity) ....

こうすると、ApplicationUserManager(UserManager)において、登録連番が定義されると思います。
また、標準では ほかに、 PhoneNumber属性も持っています。

###実現したいこと

1)アカウントを生成した後、dbを調整して、以下とします:

  • PhoneNumber属性に適当なstringが入っている(例として:"0120-000-000")
  • Id_Num属性に、登録連番(DBから振られる連番) が入っている

2)1の状態で、生成したアカウントにサインインします。

3)ページには電話番号と連番が表示されるようにしたいです。

###ソース、試したこと

以下のソースを書きましたが、IDE画面のオートコンプリートに、メソッドが出てきません。
また、クラス継承がうまくいっていないのか、

'getPhoneNumber' は 'System.Security.Principal.IIdentity' のメンバーではありません。 'getIdNum' は 'System.Security.Principal.IIdentity' のメンバーではありません。

というエラーがでて表示がうまくできません

VB.net / modules/test.vb

Module Extensions <System.Runtime.CompilerServices.Extension> Public Function GetIdNum(This As System.Security.Principal.IIdentity) As Integer? Dim userIdentity = TryCast(This, ApplicationUser) If userIdentity IsNot Nothing Then Return userIdentity.Id_Num() Else Return Nothing End If End Function <System.Runtime.CompilerServices.Extension> Public Function GetPhoneNumber(This As System.Security.Principal.IIdentity) As String Dim userIdentity = TryCast(This, ApplicationUser) If userIdentity IsNot Nothing Then Return userIdentity.PhoneNumber() Else Return Nothing End If End Function End Module

/views/index.vbhtml

@Imports Microsoft.AspNet.Identity @Imports System.Security.Principal @ModelType ApplicationUser @Code End Code ... ログインしているとあなたのIDと電話番号が表示されます [ @User.Identity.getId_Num : @User.Identity.getPhoneNumber ] ...

###具体的なゴール
@User.Identity.getPhoneNumber @User.Identity.GetIdNum を、
ログインしていればビューから呼び出せればOkです。

なお現時点で、以下は表示できています:

  • @User.Identity.GetUserName
  • @User.Identity.GetUserId
  • @User.Identity.Name
  • @HttpContext.Current.User.Identity.GetUserName

###補足情報(言語/FW/ツール等のバージョンなど)
VisualStudio 2013 VB / C# , SQLserver 2014

上記、どうぞよろしくお願い申し上げます。

dotnetuseryamag👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

3)ページには電話番号と連番が表示されるようにしたいです。

先のスレッドで紹介した記事(URL 下記)の 3 ページ目にある「リスト3」のようにして取得できませんか?

ASP.NET Identityのプロファイル情報のカスタマイズ
https://codezine.jp/article/detail/7845

上記の記事はたぶん 1.0 のもので、2.0 では多少違うかもしれませんが、基本は同じではないかと思います。

ただ、検証はしていませんのでハズレでしたらすみません・・・

投稿2017/04/07 00:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pcb

2017/04/07 04:46

はい、MVC + Identity でのモデルを無視する方法では実現可能です: [VB] ``` @*'//(↓IdentityModels.vbで定義されている)*@ @ModelType ApplicationUser @Code Dim currentUser As ProjectName.ApplicationUser If (User.Identity.IsAuthenticated) Then Dim userStore = New UserStore(Of ApplicationUser)(New ApplicationDbContext()) Dim manager = New UserManager(Of ApplicationUser)(userStore) currentUser = manager.FindById(User.Identity.GetUserId()) End If End Code IdNumは: @currentUser.IdNum <br /> 電話は: @currentUser.PhoneNumber <br /> ``` [C#] ``` @{ ProjectName.ApplicationUser currentUser = default(ProjectName.ApplicationUser); if ((User.Identity.IsAuthenticated)) { dynamic userStore = new UserStore<ApplicationUser>(new ApplicationDbContext()); dynamic manager = new UserManager<ApplicationUser>(userStore); currentUser = manager.FindById(User.Identity.GetUserId()); } } IdNumは: @currentUser.IdNum <br /> 電話は: @currentUser.PhoneNumber <br /> ``` 毎回 viewの先頭に上記のような定義をすると、モデルオブジェクト責任において 都度検索を回すことが可能です(別解としてはきっと当たり回答です)。 今回は ExtendsしたうえでUser.Identityのメンバーに加えることがゴールとなります。
退会済みユーザー

退会済みユーザー

2017/04/07 06:04

> 今回は ExtendsしたうえでUser.Identityのメンバーに加えることがゴールとなります。 どういう意味でしょう? 質問文では登録済みの情報を表示できれば良いというように読めますが?
pcb

2017/04/07 06:36

確かに実現できていることは同じなのですが、Userオブジェクトがあるのにも関わらずcurrentUserオブジェクト作るためにDBをviewで呼んでいる(modelの仕事をViewで直書きして実行している)問題と、1オブジェクトで済むはずのログイン中Userのオブジェクトが2つ、かつDB呼出しが別途起きてしまうなど、その後の事故原因になりそうな状況となっているので、Identity本来の呼出し手順を実現したく存じます...
退会済みユーザー

退会済みユーザー

2017/04/07 08:15 編集

> Userオブジェクトがあるのにも関わらずcurrentUserオブジェクト作るためにDBをviewで呼んでいる User プロパティで取得できるのは System.Security.Claims.ClaimsPrincipal オブジェクト、User.Identity プロパティで取得できるのは System.Security.Claims.ClaimsIdentity オブジェクトです。 ClaimsIdentity クラスの拡張メソッドとして GetIdNum() とか GetPhoneNumber() を実装できるのかどうか知りませんが(無理なような気がしますが)、仮にできたとしても ClaimsIdentity オブジェクトには IdNum, PhoneNumber の情報はないので、User.Identity.GetIdNum() とかした時点で結局 DB にアクセスして情報を取得せざるを得ないはずです。 あまり意味のないことではありませんか?
guest

0

自己解決

どうにか自力で答えにたどり着けたため、記録しておきます:
vbにおいてまともな日本語文献が存在しなかったので、これで皆様の助けになれば幸いです。

##VB.netでClaimで追加情報を持ちまわし、User.identityを拡張してviewに出せるようにする方法:

「毎回ユーザーストアとユーザーマネージャを呼び出しDBを叩く」をしなくてもよくなるため、パフォーマンスが向上します。

###クレームにほしい情報を追加する

クレームを追加します。このクレームはログイン時または標準では30分に再取得しようとします。ログインしていない場合は値がありません。つまり、ログインしたときの情報をもちまわしてくれることになります。
質問欄に定義してあるId_numと、MVC5テンプレートで標準の電話番号をここでは取得できるようにクレームに追加しています。

/models/ientityModels.vb

...(略)... Public Async Function GenerateUserIdentityAsync(manager As UserManager(Of ApplicationUser)) As Task(Of ClaimsIdentity) ' authenticationType が CookieAuthenticationOptions.AuthenticationType で定義されているものと一致している必要があります Dim userIdentity = Await manager.CreateIdentityAsync(Me, DefaultAuthenticationTypes.ApplicationCookie) ' ここにカスタム ユーザー クレームを追加します userIdentity.AddClaim(New Claim("PhoneNumber", Me.PhoneNumber)) userIdentity.AddClaim(New Claim("Id_Num", Me.Id_Num)) Return userIdentity End Function ...(略)...

User.Identity を拡張して、標準実装と同じやり方でメソッドを追加する

ここがハマりどころでした。Razor で @User.Identity.GetPhoneNumber のように、拡張したメソッドを開発環境に認知させるためには、module を publicで宣言する必要があります

/models/User_Claim_Extends.vb

Imports System.Security.Claims Public Module IdentityExtensions <System.Runtime.CompilerServices.Extension> Public Function GetIdNum(User As System.Security.Principal.IIdentity) As Integer? If (User.IsAuthenticated) Then Dim claim = DirectCast(User, ClaimsIdentity).FindFirst("Id_Num") Return If((claim IsNot Nothing), claim.Value, Nothing) Else Return Nothing End If End Function <System.Runtime.CompilerServices.Extension> Public Function GetPhoneNumber(User As System.Security.Principal.IIdentity) As String If (User.IsAuthenticated) Then Dim claim = DirectCast(User, ClaimsIdentity).FindFirst("PhoneNumber") Return If((claim IsNot Nothing), claim.Value, Nothing) Else Return Nothing End If End Function End Module

ビューに表示したい情報を足す

IdNumは: @User.Identity.GetIdNum <br /> 電話は: @User.Identity.GetPhoneNumber <br />

↓ 実行例)

IdNumは: 2 電話は: 0120-000-000

追加情報:

ログイン中の再取得タイミング変更を、以下の時間をサーバに負荷にならない程度に短く変更するとよいかもしれません。

/App_Start/Startup.Auth.vb

validateInterval:=TimeSpan.FromMinutes(30),

validateInterval:=TimeSpan.FromSeconds(20),

具体的には、Startup.Auth.vb にあるパラメータを、上記のように変更すると、ログイン後、または最後にGenerateUserIdentityAsyncを訪れてクレーム周りを更新(たいていはページ読み込みと同義)したあと指定時間が経過したら、GenerateUserIdentityAsyncを巡回するようになります。

これにより上記の例ですと、Administratorを想定したアカウントが変更を掛けると遅くとも20秒以内で、自動で情報が更新できるを実現することが可能になります。

なお、moduleのほう、namespaceで囲っていないので、どこからでも見られるようになっていますが、可能で居あればnamespaceで囲って、Importsできるようにするほうが無難(スマート)です。

投稿2017/04/08 09:35

編集2017/04/08 09:44
pcb

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問