Web アプリケーションプロジェクトで新規ユーザー登録をする際に、ユーザーの漢字の氏名、住所などのユーザープロファイル情報を取得し、ASP.NET プロファイルを使用して保存する方法の紹介です。
先の記事 ユーザー登録時のプロファイル情報取得 では、Web サイトプロジェクトを利用しました。その場合は、どのページでも Profile プロパティでプロファイル・データにアクセスできるようになります。
例えば、以下のように、String 型の KanjiName を profile の properties の add 要素 に定義したとします。
<profile>
<properties>
<add name="KanjiName" />
</properties>
</profile>
すると、ProfileBase クラス を継承する ProfileCommon クラスが自動的に作成され、profile の properties の add 要素 に定義されているそれぞれのプロパティの get/set アクセサが ProfileCommon クラスに追加されます。以下のような感じになると思います。(実際に自動生成されたコードを見たわけではないので想像ですが)
public class ProfileCommon : ProfileBase
{
public virtual string KanjiName
{
get
{
return (String) HttpContext.Current.Profile.
GetPropertyValue("KanjiName");
}
set
{
HttpContext.Current.Profile.
SetPropertyValue("KanjiName", value);
}
}
}
さらに、各ページに、ProfileCommon クラスのインスタンスを取得するため、以下のような Profile プロパティが自動的に追加されます。
protected ProfileCommon Profile
{
get
{
return (ProfileCommon)this.Context.Profile;
}
}
それゆえ、Web サイトプロジェクトでは、コードは一行も書かなくても、どのページでも Profile.KanjiName プロパティを使ってプロファイル・データにアクセスできるようになります。
しかしながら、Web アプリケーションプロジェクトではそうはいきません。(Web アプリケーションプロジェクトと Web サイトプロジェクトの違いについては MSDN ライブラリ を参照してください)
何故なら ProfileCommon クラスや Profile プロパティは自動的に定義されないからです。
そのあたりのことは、MSDN ライブラリの チュートリアル : Visual Studio の Web サイト プロジェクトから Web アプリケーション プロジェクトへの変換 の「プロファイル オブジェクト コードの変換」のセクションに説明があります。
KanjiName の場合を例に取ると、以下のように手動で ProfileCommon を定義する必要があります。この場合、ProfileCommon は ProfileBase を継承する必要はありません。
public class ProfileCommon
{
public virtual string KanjiName
{
get
{
return (String) HttpContext.Current.Profile.
GetPropertyValue("KanjiName");
}
set
{
HttpContext.Current.Profile.
SetPropertyValue("KanjiName", value);
}
}
}
次に、ProfileCommon クラスのインスタンスの 1 つである Profile を、次のコード例のように、プロファイル システムを使用する必要があるページに追加します。
public partial class _Default : System.Web.UI.Page
{
ProfileCommon Profile = new ProfileCommon();
protected void Page_Load(object sender, EventArgs e)
{
string kanjiName = Profile.KanjiName;
if (String.IsNullOrEmpty(kanjiName))
{
Label1.Text = "漢字名は設定されていません。";
}
else
{
Label1.Text = Server.HtmlEncode(kanjiName);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
Profile.KanjiName = TextBox1.Text;
Label1.Text = Server.HtmlEncode(Profile.KanjiName);
}
else
{
Label2.Text = "ログインしていないと設定できません。";
}
}
}
なお、web.config に、データベースとのプロファイル・データのやり取りのためプロバイダの設定は必要です。以下の providers の設定は、Visual Studio 2010 が自動的に生成する profile 要素の例です。profile の properties の add 要素に KanjiName を設定する必要はありませんの設定も必要です(2011/12/6 誤記訂正。下の追記参照)。anonymousIdentification の設定は不要です。
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="ApplicationServices"
applicationName="/"/>
</providers>
<!-- やはり KnajiName の設定は必要 -->
<properties>
<add name="KanjiName" />
</properties>
</profile>
以上の手順で、認証済みユーザーのプロファイルの取得、設定はできるようになります。
ただし、新規ユーザー登録をする際に、ユーザーの漢字の氏名などの情報を取得し、プロファイルを使用して保存する場合は Profile.KanjiName = TextBox1.Text; のようにしてもうまくいきません。
何故なら、その時点ではまだユーザーが認証されていないので、SetPropertyValue メソッドで例外がスローされてしまうからです。
以下のように、ProfileBase.Create メソッド を使って指定したユーザー名のプロファイルのインスタンスを作成し、それを操作するとうまくいきます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Profile;
namespace WebApplication1.Account
{
public partial class CreateUser : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CreateUserWizard1.ContinueDestinationPageUrl =
Request.QueryString["ReturnUrl"];
}
protected void CreateUserWizard1_CreatedUser(
object sender, EventArgs e)
{
ProfileBase profile =
ProfileBase.Create(CreateUserWizard1.UserName, true);
profile.SetPropertyValue(
"KanjiName", lastName.Text + " " + firstName.Text);
profile.Save();
FormsAuthentication.SetAuthCookie(
CreateUserWizard1.UserName, false);
string continueUrl =
CreateUserWizard1.ContinueDestinationPageUrl;
if (String.IsNullOrEmpty(continueUrl))
{
continueUrl = "~/";
}
Response.Redirect(continueUrl);
}
}
}
---------- 2011/12/6 追記 ----------
先に作ったプロジェクトでは、何故か KanjiName の設定がなくても問題ありませんでした。
しかし、新たに別プロジェクトを作って、同様なコードを試してみたところ、KanjiName の設定がないと Profile.KanjiName プロパティで以下の例外がスローされます。
"System.Configuration.SettingsPropertyNotFoundException: 設定プロパティ 'KanjiName' が見つかりませんでした。"
理由は不明です(調査中)。違いは、先に作ったプロジェクトは .ASPXANONYMOUS クッキーが発行されること(anonymousIdentification は設定してないのに)と、開発マシンの Vista の IIS7 上で動かしていること(新たに作った方は開発サーバー)の 2 点ぐらいです。後者は関係なさそうですが、前者が怪しい感じです。