回答:
今日も同じ問題があり、多くのことを学びました。
Visual Studioには、「Webサイトプロジェクト」と「Webアプリケーションプロジェクト」の2種類のプロジェクトがあります。私にとって完全に謎である理由により、Webアプリケーションプロジェクトはプロファイルを使用できません。直接...強く型付けされたクラスはWeb.configファイルから魔法のように生成されないので、独自にロールする必要があります。
MSDNのサンプルコードは、Webサイトプロジェクトを使用していることを前提としています。これらの<profile>
セクションでは、セクションをyour Web.config
and party on Profile.
propertyに追加するように指示されていますが、Webアプリケーションプロジェクトでは機能しません。
自分でロールするには2つの選択肢があります。
(1)Web Profile Builderを使用します。これは、Visual Studioに追加するカスタムツールで、Web.configの定義から必要なProfileオブジェクトを自動的に生成します。
コードをこの追加のツールに依存してコンパイルしたくなかったので、これを選択しませんでした。このツールが必要であることに気付かずにコードをビルドしようとしたときに問題が発生する可能性がありました。
(2)ProfileBase
カスタムプロファイルを表すために派生する独自のクラスを作成します。これは見た目より簡単です。以下は、 "FullName"文字列プロファイルフィールドを追加する非常に単純な例です。
あなたのweb.configで:
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>
AccountProfile.csというファイルで:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;
namespace YourNamespace
{
public class AccountProfile : ProfileBase
{
static public AccountProfile CurrentUser
{
get { return (AccountProfile)
(ProfileBase.Create(Membership.GetUser().UserName)); }
}
public string FullName
{
get { return ((string)(base["FullName"])); }
set { base["FullName"] = value; Save(); }
}
// add additional properties here
}
}
プロファイル値を設定するには:
AccountProfile.CurrentUser.FullName = "Snoopy";
プロファイル値を取得するには
string x = AccountProfile.CurrentUser.FullName;
<profile ..><properties><add name="..">
AccountProfileクラスで誤ってプロファイルプロパティを定義すると、「このプロパティはすでに定義されています」というメッセージが表示されます。web.configでプロパティを削除することで簡単に修正できます。
WebアプリケーションプロジェクトはProfileCommonオブジェクトを引き続き使用できますが、実行時のみです。そのコードはプロジェクト自体で生成されるのではなく、クラスはASP.Netによって生成され、実行時に存在します。
オブジェクトに到達する最も簡単な方法は、以下に示すように動的型を使用することです。
Web.configファイルで、プロファイルプロパティを宣言します。
<profile ...
<properties>
<add name="GivenName"/>
<add name="Surname"/>
</properties>
次に、プロパティにアクセスします。
dynamic profile = ProfileBase.Create(Membership.GetUser().UserName);
string s = profile.GivenName;
profile.Surname = "Smith";
プロファイルプロパティの変更を保存するには:
profile.Save();
上記は、動的型を快適に使用でき、コンパイル時のチェックとインテリセンスの欠如を気にしない場合は問題なく機能します。
これをASP.Net MVCで使用する場合、動的プロファイルオブジェクトをビューに渡すと、HTMLヘルパーメソッドが動的な「モデル」オブジェクトでうまく機能しないため、追加の作業を行う必要があります。HTMLヘルパーメソッドに渡す前に、静的に型指定された変数にプロファイルプロパティを割り当てる必要があります。
// model is of type dynamic and was passed in from the controller
@Html.TextBox("Surname", model.Surname) <-- this breaks
@{ string sn = model.Surname; }
@Html.TextBox("Surname", sn); <-- will work
Joelが前述したようにカスタムプロファイルクラスを作成する場合、ASP.NetはProfileCommonクラスを生成しますが、カスタムプロファイルクラスから継承します。カスタムプロファイルクラスを指定しない場合、ProfileCommonはSystem.Web.Profile.ProfileBaseを継承します。
独自のプロファイルクラスを作成する場合は、カスタムプロファイルクラスで既に宣言したWeb.configファイルでプロファイルプロパティを指定しないようにしてください。ASP.NetがProfileCommonクラスを生成しようとすると、コンパイラエラーが発生します。
プロファイルはWebアプリケーションプロジェクトでも使用できます。プロパティは、デザイン時またはプログラムでWeb.configで定義できます。Web.configで:
<profile enabled="true" automaticSaveEnabled="true" defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="TestRolesNProfiles"/>
</providers>
<properties>
<add name="FirstName"/>
<add name="LastName"/>
<add name ="Street"/>
<add name="Address2"/>
<add name="City"/>
<add name="ZIP"/>
<add name="HomePhone"/>
<add name="MobilePhone"/>
<add name="DOB"/>
</properties>
</profile>
またはプログラムで、ProfileSectionをインスタンス化し、ProfilePropertySettingsとProfilePropertySettingsColletionを使用して個々のプロパティを作成して、プロファイルセクションを作成します。これらはすべてSystem.Web.Configuration名前空間にあります。プロファイルのこれらのプロパティを使用するには、System.Web.Profile.ProfileBaseオブジェクトを使用します。プロファイルを使用してプロファイルプロパティにアクセスすることはできません。構文は上記のとおりですが、ProfileBaseをインスタンス化し、SetPropertyValue( " PropertyName ")およびGetPropertyValue {" PropertyName ")を次のように使用して簡単に実行できます。
ProfileBase curProfile = ProfileBase.Create("MyName");
または、現在のユーザーのプロファイルにアクセスするには:
ProfileBase curProfile = ProfileBase.Create(System.Web.Security.Membership.GetUser().UserName);
curProfile.SetPropertyValue("FirstName", this.txtName.Text);
curProfile.SetPropertyValue("LastName", this.txtLname.Text);
curProfile.SetPropertyValue("Street", this.txtStreet.Text);
curProfile.SetPropertyValue("Address2", this.txtAdd2.Text);
curProfile.SetPropertyValue("ZIP", this.txtZip.Text);
curProfile.SetPropertyValue("MobilePhone", txtMphone.Text);
curProfile.SetPropertyValue("HomePhone", txtHphone.Text);
curProfile.SetPropertyValue("DOB", txtDob.Text);
curProfile.Save();
ProfileBase
オブジェクトを作成してGetPropertyValue("PropName")
?を呼び出すだけで、どこからでもユーザーデータにアクセスできます。
Visual Studioで新しいWebサイトプロジェクトを作成すると、プロファイルから返されたオブジェクトが(自動的に)生成されます。WebアプリケーションプロジェクトまたはMVCプロジェクトを作成するときは、独自にロールバックする必要があります。
これはおそらく実際よりも難しいように聞こえます。次のことを行う必要があります。
Webアプリケーションプロジェクトを使用している場合、すぐに使用できる設計時のプロファイルオブジェクトにはアクセスできません。これはおそらくあなたのためにそれを行うユーティリティです:http : //weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx。個人的には、そのユーティリティによってプロジェクトでエラーが発生したため、ProfileBaseから継承するために自分のプロファイルクラスをロールすることになりました。全然難しくありませんでした。
カスタムクラスを作成するためのMSDNウォークスルー(別名Joelのメソッド):http :
//msdn.microsoft.com/en-us/magazine/cc163624.aspx
WebプロファイルBuilderは私のために素晴らしい仕事しました。それが生成したクラスには、Joelの投稿で説明されているクラスよりも多くのクラスが含まれています。それが実際に必要か有用かどうかはわかりません。
とにかく、クラスを生成する簡単な方法を探しているが、外部ビルドツールの依存関係が必要ない場合は、いつでもできます。
または(テストされていませんが、機能する可能性があります)
この2番目のアプローチが機能する場合、誰かが将来の参考のために私に知らせることができます
ジョエル・スポルスキーの答えに追加したいだけです
私は彼のソリューションを実装し、見事に機能しました-Cudos!
私が使用したログインユーザーではないユーザープロファイルを取得したい場合:
web.config:
<connectionStrings>
<clear />
<add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" />
</connectionStrings>
そして
<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/>
</providers>
そして私のカスタムクラス:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;
namespace NameSpace
{
public class AccountProfile : ProfileBase
{
static public AccountProfile CurrentUser
{
get
{
return (AccountProfile)
(ProfileBase.Create(Membership.GetUser().UserName));
}
}
static public AccountProfile GetUser(MembershipUser User)
{
return (AccountProfile)
(ProfileBase.Create(User.UserName));
}
/// <summary>
/// Find user with matching barcode, if no user is found function throws exception
/// </summary>
/// <param name="Barcode">The barcode to compare against the user barcode</param>
/// <returns>The AccountProfile class with matching barcode or null if the user is not found</returns>
static public AccountProfile GetUser(string Barcode)
{
MembershipUserCollection muc = Membership.GetAllUsers();
foreach (MembershipUser user in muc)
{
if (AccountProfile.GetUser(user).Barcode == Barcode)
{
return (AccountProfile)
(ProfileBase.Create(user.UserName));
}
}
throw new Exception("User does not exist");
}
public bool isOnJob
{
get { return (bool)(base["isOnJob"]); }
set { base["isOnJob"] = value; Save(); }
}
public string Barcode
{
get { return (string)(base["Barcode"]); }
set { base["Barcode"] = value; Save(); }
}
}
}
魅力のように動作します...