답변:
오늘도 같은 문제가 있었고 많은 것을 배웠습니다.
Visual Studio에는 "웹 사이트 프로젝트"와 "웹 응용 프로그램 프로젝트"라는 두 종류의 프로젝트가 있습니다. 나에게 완전한 미스터리 인 이유로 웹 애플리케이션 프로젝트는 프로필을 사용할 수 없습니다 . 직접적으로 ... 강력한 형식의 클래스는 Web.config 파일에서 마법처럼 생성되지 않으므로 직접 롤링해야합니다.
MSDN의 샘플 코드는 사용자가 웹 사이트 프로젝트를 사용하고 있다고 가정 하고 속성<profile>
을 사용하여 섹션을 추가하라고 지시 하지만 웹 응용 프로그램 프로젝트에서는 작동하지 않습니다.Web.config
Profile.
두 가지 선택 사항이 있습니다.
(1) 웹 프로필 작성기를 사용합니다 . 이것은 Web.config의 정의에서 필요한 프로필 개체를 자동으로 생성하는 Visual Studio에 추가하는 사용자 지정 도구입니다.
이 도구가 필요하다는 사실을 깨닫지 못하고 내 코드를 빌드하려고 할 때 다른 사람에게 문제를 일으킬 수있는이 추가 도구를 컴파일하는 데 내 코드가 의존하는 것을 원하지 않았기 때문에 이렇게하지 않기로 선택했습니다.
(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에서 속성을 제거하면 쉽게 수정할 수있는 "이 속성은 이미 정의되었습니다."라는 메시지가 표시됩니다.
웹 애플리케이션 프로젝트는 여전히 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.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에서 새 웹 사이트 프로젝트를 만들면 프로필에서 반환되는 개체가 자동으로 생성됩니다. 웹 응용 프로그램 프로젝트 또는 MVC 프로젝트를 만들 때 직접 롤링해야합니다.
이것은 아마도 그것보다 더 어렵게 들릴 것입니다. 다음을 수행해야합니다.
웹 응용 프로그램 프로젝트를 사용하는 경우 디자인 타임에 바로 사용할 수있는 프로필 개체에 액세스 할 수 없습니다. 다음은 당신을위한 유틸리티입니다 : http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . 개인적으로 그 유틸리티는 내 프로젝트에서 오류를 일으켜 ProfileBase에서 상속하기 위해 내 자신의 프로필 클래스를 롤링했습니다. 전혀 어렵지 않았습니다.
사용자 지정 클래스 (Joel의 메서드라고도 함) 만들기를위한 MSDN 연습 :
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
나는 또한 같은 문제를 겪고 있었다. 그러나 ProfileBase에서 상속하는 클래스를 만드는 대신 HttpContext를 사용했습니다.
web.config 파일에서 다음과 같이 속성을 지정합니다.-
이제 다음 코드를 작성하십시오.-
코드를 컴파일하고 실행합니다. 다음과 같은 출력이 표시됩니다.-
웹 프로필 Builder는 나를 위해 큰 일했습니다. 생성 된 클래스는 Joel의 게시물에 설명 된 것보다 훨씬 더 많이 포함되어 있습니다. 실제로 필요하거나 유용했는지 여부는 모르겠습니다.
어쨌든 클래스를 생성하는 쉬운 방법을 찾고 있지만 외부 빌드 도구 종속성을 원하지 않는 사람들을 위해 언제든지 할 수 있습니다.
또는 (예상되지 않았지만 작동 할 수 있음)
이 두 번째 접근 방식이 효과가 있다면 누군가가 나중에 참조 할 수 있도록 알려줄 수 있습니다.
Joel Spolsky의 답변에 추가하고 싶습니다.
나는 그의 솔루션을 구현하여 훌륭하게 작동했습니다.-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(); }
}
}
}
매력처럼 작동합니다 ...