Joelがここで説明しているように、カスタムProfileオブジェクトをコードに実装しました。
ただし、新しいユーザーを作成しているときに機能させることはできません。私がこれをするとき:
Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");
ユーザーが作成され、データベース内のロールに追加されますが、HttpContext.Current.User
それでも空であり、Membership.GetUser()
nullを返すため、これは(Joelのコードから)機能しません。
static public AccountProfile CurrentUser
{
get { return (AccountProfile)
(ProfileBase.Create(Membership.GetUser().UserName)); }
}
AccountProfile.CurrentUser.FullName = "Snoopy";
プロファイルプロパティをそのように呼び出しMembership.GetUser(userName)
て設定しようとしましたが、設定されたプロパティは空のままであり、呼び出しAccountProfile.CurrentUser(userName).Save()
てもデータベースには何も入れられません。Membership.ValidateUser
また、、などを呼び出して、ユーザーが有効でログインしていることを示してみましたFormsAuthentication.SetAuthCookie
が、現在のユーザーはまだnullまたは匿名です(ブラウザーのCookieの状態によって異なります)。
解決済み(さらに編集、以下を参照):フランシ・ペノフの説明といくつかの実験に基づいて、私は問題を理解しました。Joelのコードと私が試したバリエーションは、既存のプロファイルでのみ機能します。プロファイルが存在しない場合、ProfileBase.Create(userName)
呼び出されるたびに新しい空のオブジェクトを返します。プロパティを設定することはできますが、アクセスするたびに新しいインスタンスが返されるため、プロパティが「固定」されることはありません。HttpContext.Current.User
newGenericPrincipal
に設定すると、Userオブジェクトは提供されますが、Profileオブジェクトは提供されません。また、新しい空のオブジェクトをポイントします。ProfileBase.Create(userName)
HttpContext.Current.Profile
同じリクエストで新しく作成されたユーザーのプロファイルを作成する場合は、を呼び出す必要がありますHttpContext.Current.Profile.Initialize(userName, true)
。次に、初期化されたプロファイルにデータを入力して保存すると、今後のリクエストで名前でアクセスできるようになるため、Joelのコードが機能します。作成直後にプロファイルを作成/アクセスする必要がある場合は、内部でのみ使用しています。HttpContext.Current.Profile
その他のリクエストでは、を使用しProfileBase.Create(userName)
、そのバージョンのみを公開しました。
フランシが正しいことに注意してください。ユーザー(およびロール)を作成し、最初のラウンドトリップで認証済みとして設定し、ユーザーにログインするように依頼すると、プロファイルにはるかに簡単にアクセスできるようになります。後続のリクエストでJoelのコードを介して。私を驚かせたのは、初期化せずにユーザーを作成するとすぐにロールにアクセスできることですが、プロファイルにはアクセスできません。
私の新しいAccountProfileコード:
public static AccountProfile CurrentUser
{
get
{
if (Membership.GetUser() != null)
return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
else
return null;
}
}
internal static AccountProfile NewUser
{
get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}
新規ユーザーの作成:
MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();
その後のアクセス:
if (Membership.ValidateUser(userName, password))
{
string name = AccountProfile.CurrentUser.FullName;
}
認証のライフサイクルを説明してくれたFranciにさらに感謝します-検証関数でFormsAuthentication.SetAuthCookieを呼び出していますが、User.Identity.IsAuthenticatedは後続のリクエストまで真にならないため、成功を示すブール値を返します。
改訂:私はばかです。上記の説明は狭い範囲で機能しますが、主要な問題を解決しません。CurrentUserを呼び出すと、既存のプロファイルであるかどうかに関係なく、オブジェクトの新しいインスタンスが毎回返されます。プロパティとして定義されているので、私はこれについて考えていませんでした、そして書いた:
AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();
これは(もちろん)機能しません。そのはず:
AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();
この基本的なポイントを完全に見落とすのは私自身の責任ですが、CurrentUserをプロパティとして宣言することは、それが操作可能なオブジェクトであることを意味すると思います。代わりに、として宣言する必要がありますGetCurrentUser()
。