WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

Web アプリケーションプロジェクトと Profile

by WebSurfer 2011年12月4日 16:34

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 点ぐらいです。後者は関係なさそうですが、前者が怪しい感じです。

Tags:

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar