Câu trả lời:
Tôi đã gặp vấn đề tương tự ngày hôm nay, và đã học được rất nhiều điều.
Có hai loại dự án trong Visual Studio - "Dự án trang web" và "Dự án ứng dụng web". Vì những lý do hoàn toàn bí ẩn đối với tôi, các Dự án Ứng dụng Web không thể sử dụng Hồ sơ. trực tiếp ... lớp được gõ mạnh không được tạo một cách kỳ diệu cho bạn từ tệp Web.config, vì vậy bạn phải tự cuộn.
Các mẫu mã trong MSDN giả sử bạn đang sử dụng một dự án trang web, và họ nói với bạn chỉ để thêm một <profile>
phần để bạn Web.config
đảng và về với Profile.
bất động sản , nhưng điều đó không làm việc trong các dự án ứng dụng Web.
Bạn có hai lựa chọn để cuộn của riêng mình:
(1) Sử dụng Trình tạo Hồ sơ Web . Đây là một công cụ tùy chỉnh bạn thêm vào Visual Studio. Công cụ này tự động tạo đối tượng Hồ sơ bạn cần từ định nghĩa của bạn trong Web.config.
Tôi đã chọn không làm điều này, vì tôi không muốn mã của mình phụ thuộc vào công cụ bổ sung này để biên dịch, điều này có thể gây ra sự cố cho người khác khi họ cố gắng tạo mã của tôi mà không nhận ra rằng họ cần công cụ này.
(2) Tạo lớp của riêng bạn có nguồn gốc ProfileBase
để đại diện cho hồ sơ tùy chỉnh của bạn. Điều này là dễ dàng hơn nó có vẻ. Dưới đây là một ví dụ rất đơn giản để thêm trường cấu hình chuỗi "FullName":
Trong web.config của bạn:
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>
Trong một tệp có tên 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
}
}
Để đặt giá trị hồ sơ:
AccountProfile.CurrentUser.FullName = "Snoopy";
Để nhận được giá trị hồ sơ
string x = AccountProfile.CurrentUser.FullName;
<profile ..><properties><add name="..">
cũng như trong lớp AccountProfile, bạn sẽ nhận được thông báo "Thuộc tính này đã được xác định", dễ dàng sửa bằng cách xóa các thuộc tính trong web.config.
Dự án ứng dụng web vẫn có thể sử dụng đối tượng ProfileCommon nhưng chỉ trong thời gian chạy. Mã cho nó chỉ không được tạo ra trong chính dự án mà là lớp được tạo bởi ASP.Net và hiện diện trong thời gian chạy.
Cách đơn giản nhất để truy cập đối tượng là sử dụng kiểu động như minh họa bên dưới.
Trong tệp Web.config, khai báo các thuộc tính cấu hình:
<profile ...
<properties>
<add name="GivenName"/>
<add name="Surname"/>
</properties>
Sau đó, để truy cập các thuộc tính:
dynamic profile = ProfileBase.Create(Membership.GetUser().UserName);
string s = profile.GivenName;
profile.Surname = "Smith";
Để lưu các thay đổi đối với thuộc tính hồ sơ:
profile.Save();
Ở trên hoạt động tốt nếu bạn cảm thấy thoải mái khi sử dụng các kiểu động và không ngại việc thiếu kiểm tra thời gian biên dịch và intellisense.
Nếu bạn sử dụng điều này với ASP.Net MVC, bạn phải thực hiện một số công việc bổ sung nếu bạn chuyển đối tượng cấu hình động đến dạng xem của mình vì các phương thức trình trợ giúp HTML không hoạt động tốt với các đối tượng "mô hình" động. Bạn sẽ phải gán các thuộc tính hồ sơ cho các biến được nhập tĩnh trước khi chuyển chúng đến các phương thức trợ giúp 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
Nếu bạn tạo một lớp hồ sơ tùy chỉnh, như Joel đã mô tả ở trên, ASP.Net sẽ vẫn tạo lớp ProfileCommon nhưng nó sẽ kế thừa từ lớp hồ sơ tùy chỉnh của bạn. Nếu bạn không chỉ định một lớp cấu hình tùy chỉnh, ProfileCommon sẽ kế thừa từ System.Web.Profile.ProfileBase.
Nếu bạn tạo lớp hồ sơ của riêng mình, hãy đảm bảo rằng bạn không chỉ định thuộc tính hồ sơ trong tệp Web.config mà bạn đã khai báo trong lớp hồ sơ tùy chỉnh của mình. Nếu bạn thực hiện ASP.Net sẽ báo lỗi trình biên dịch khi nó cố gắng tạo lớp ProfileCommon.
Hồ sơ cũng có thể được sử dụng trong các Dự án Ứng dụng Web. Các thuộc tính có thể được xác định trong Web.config tại thời điểm thiết kế hoặc theo chương trình. Trong 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>
hoặc lập trình, tạo ra phần Tiểu sử của instantiating một ProfileSection và tạo ra đặc tính cá nhân sử dụng ProfilePropertySettings và ProfilePropertySettingsColletion , tất cả trong số đó là ở System.Web.Configuration Namespace. Để sử dụng các thuộc tính đó của cấu hình, hãy sử dụng Đối tượng System.Web.Profile.ProfileBase. Các thuộc tính hồ sơ không thể được truy cập với hồ sơ. cú pháp như đã đề cập ở trên, nhưng có thể dễ dàng thực hiện bằng cách khởi tạo một ProfileBase và sử dụng SetPropertyValue (" PropertyName ") và GetPropertyValue {" PropertyName ") như sau:
ProfileBase curProfile = ProfileBase.Create("MyName");
hoặc để truy cập hồ sơ của người dùng hiện tại:
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
đối tượng mới và gọi GetPropertyValue("PropName")
?
Khi bạn tạo một dự án trang Web mới trong Visual Studio thì đối tượng được trả về từ Hồ sơ sẽ được (tự động) tạo cho bạn. Khi bạn tạo một dự án ứng dụng Web hoặc một dự án MVC, bạn sẽ phải tự thực hiện.
Điều này có lẽ nghe có vẻ khó khăn hơn nó. Bạn cần làm như sau:
Nếu bạn đang sử dụng một dự án ứng dụng web, bạn không thể truy cập đối tượng Hồ sơ vào lúc thiết kế sẵn sàng. Đây là một tiện ích được cho là làm điều đó cho bạn: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Về mặt cá nhân, tiện ích đó đã gây ra lỗi trong dự án của tôi nên tôi đã kết thúc việc cuộn lớp hồ sơ của riêng mình để kế thừa từ ProfileBase. Nó không khó để làm gì cả.
Hướng dẫn MSDN để tạo một lớp tùy chỉnh (còn gọi là phương pháp của Joel):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
Tôi cũng đang gặp phải vấn đề tương tự. Nhưng thay vì tạo một lớp kế thừa từ ProfileBase, tôi đã sử dụng HttpContext.
Chỉ định các thuộc tính trong tệp web.config như sau: -
Bây giờ, hãy viết đoạn mã sau: -
Biên dịch và chạy mã. Bạn sẽ nhận được kết quả sau: -
Trình tạo hồ sơ web làm việc rất tốt cho tôi. Lớp mà nó tạo ra có rất nhiều thứ trong đó hơn là được mô tả trong bài đăng của Joel. Tôi không biết nó có thực sự cần thiết hay hữu ích hay không.
Dù sao, đối với những người đang tìm kiếm một cách dễ dàng để tạo lớp, nhưng không muốn có sự phụ thuộc của công cụ xây dựng bên ngoài, bạn luôn có thể
HOẶC (chưa được kiểm tra nhưng có thể chỉ hoạt động)
nếu cách tiếp cận thứ hai này hoạt động hiệu quả, ai đó có thể cho tôi biết để tham khảo trong tương lai
Chỉ muốn thêm vào câu trả lời của Joel Spolsky
Tôi đã triển khai giải pháp của anh ấy, hoạt động xuất sắc btw - Cudos!
Đối với bất kỳ ai muốn nhận hồ sơ người dùng không phải là người dùng đã đăng nhập mà tôi đã sử dụng:
web.config:
<connectionStrings>
<clear />
<add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" />
</connectionStrings>
và
<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/>
</providers>
Và sau đó là lớp tùy chỉnh của tôi:
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(); }
}
}
}
Hoạt động như một sự quyến rũ ...
Bài viết tuyệt vời,
Chỉ cần lưu ý trên web.config nếu bạn không chỉ định thuộc tính kế thừa trong phần tử hồ sơ, bạn sẽ cần chỉ định từng thuộc tính hồ sơ cá nhân bên trong phần tử hồ sơ trên web.config như bên dưới
<properties>
<clear/>
<add name="property-name-1" />
<add name="property-name-2" />
..........
</properties>