18

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.UsernewGenericPrincipal 設定すると、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()

4

3 に答える 3

7

ユーザーを作成すると、ユーザーのリストに追加されるだけです。ただし、これは現在の要求に対して新しいユーザーを認証または承認しません。また、現在のリクエストコンテキストまたは後続のリクエストでユーザーを認証する必要があります。

Membership.ValidateUser資格情報のみを検証しますが、現在または後続の要求に対してユーザーを認証しません。FormsAuthentication.SetAuthCookieは応答ストリームに認証チケットを設定するため、次の要求が認証されますが、現在の要求の状態には影響しません。

ユーザーを認証する最も簡単な方法は、電話をかけるFormsAuthentication.RedirectFromLoginPageことです(アプリでフォーム認証を使用していると仮定します)。ただし、これにより、実際には新しいHTTPリクエストが発生し、ユーザーが認証されます。

または、現在のリクエストを処理するためのロジックを続行する必要があるが、ユーザーを認証したい場合は、を作成しGenericPrincipal、それに新しいユーザーのIDを割り当てて、HttpContext.Userそのプリンシパルに設定できます。

于 2010-03-30T18:01:02.753 に答える
1

analogIdentificationを有効にすると、このアプローチで問題が発生します。Membership.GetUser()。UserNameではなく、HttpContext.Profile.UserNameを使用することをお勧めします。

このような...

private UserProfile _profile;
private UserProfile Profile
{
    get { return _profile ?? (_profile = (UserProfile)ProfileBase.Create(HttpContext.Profile.UserName)); }
}

ヒント:SqlProfileProvider-プロジェクトでProfile.GetProfile()を使用できますか?

于 2012-01-21T21:27:32.397 に答える
0

まず、調査結果を共有してくれた@Jeremyに感謝します。あなたは私が正しい方向に進むのを手伝ってくれました。第二に、この古い投稿をぶつけてすみません。うまくいけば、これは誰かが点をつなぐのに役立つでしょう。

最終的にこれを機能させる方法は、プロファイルクラス内で次の静的メソッドを使用することでした。

internal static void InitializeNewMerchant(string username, Merchant merchant)
{
    var profile = System.Web.HttpContext.Current.Profile as MerchantProfile;
    profile.Initialize(username, true);
    profile.MerchantId = merchant.MerchantId;
    profile.Save();
}
于 2011-07-01T22:20:11.007 に答える