Làm cách nào để gán giá trị Hồ sơ?


110

Tôi không biết mình đang thiếu cái gì, nhưng tôi đã thêm thuộc tính Hồ sơ trong tệp Web.config nhưng không thể truy cập Hồ sơ. Mục trong mã hoặc tạo một hồ sơ mới.

Câu trả lời:


179

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;

10
Bản thân StackOverflow không sử dụng cấu hình. Mã này có lẽ không đủ nhanh cho một trang web có 1.000.000 lượt xem mỗi ngày. Tôi đang làm việc trong một dự án khác khi tôi viết nó.
Joel Spolsky

1
Đó là lỗi của riêng tôi, nhưng tôi đã vật lộn khá lâu với việc thiết lập các thuộc tính sau khi gọi CurrentUser. Vì CurrentUser khởi tạo và trả về một phiên bản mới mỗi lần, tôi có thể đề xuất định nghĩa nó như một phương thức không? Không cần suy nghĩ, tôi đã viết thế này: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); mà không hoạt động. Nó phải là: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "Snoopy"; currentProfile.OtherProperty = "ABC"; currentProfile.Save ();
Jeremy Gruenwald

1
Loại này không phải đánh bại toàn bộ mục đích của Sơ Sơ sao? Bạn không thể sử dụng "Profile.MyProperty", bạn phải sử dụng lớp học tự phát triển của riêng mình, lớp này không được thiết lập trên mọi trang theo cách Hồ sơ tự động. Tất cả những gì làm được là cho phép bạn sử dụng tính năng Save () mà không cần phải viết mã.
Mike K,

7
Dự án Ứng dụng Web không thể sử dụng Hồ sơ.
Joel Spolsky

2
Nếu bạn vô tình xác định thuộc tính hồ sơ trong cấu hình web <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.
Zachary Scott

17

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.


tôi không thể lưu hồ sơ. lỗi này là: 'ProfileCommon' không chứa một định nghĩa cho 'tiết kiệm'
Jimmy

2
@Salman: ProfileCommon có nguồn gốc từ System.Web.Profile.ProfileBase có phương thức Save (). Vui lòng kiểm tra xem viết hoa của bạn có đúng không. Xem: msdn.microsoft.com/en-us/library/…
colivier

13

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 ProfilePropertySettingsProfilePropertySettingsColletion , 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();

1
Tôi không biết tại sao điều này không nhận được 1000 phiếu bầu. Nó là vô cùng hữu ích.
pghcpa

Tôi đoán không ai làm phiền khi cuộn xuống đây. Đây là Vàng, cảm ơn Bede! Sau khi lưu dữ liệu ở trên, tôi có thể truy cập dữ liệu người dùng từ bất kỳ đâu đơn giản bằng cách tạo một ProfileBaseđối tượng mới và gọi GetPropertyValue("PropName")?
seebiscuit

Thật tuyệt vời, đây là cách duy nhất phù hợp với tôi. Thans Bede
Emanuel Pirovano 26/1017

Vấn đề đầu tiên, làm thế nào tôi có thể sử dụng truy cập vào trang khác?
Emanuel Pirovano

8

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:

  • Tạo cơ sở dữ liệu bằng cách sử dụng aspnet_regsql.exe Công cụ này được cài đặt cùng với .NET framework.
  • Viết một lớp dẫn xuất từ ​​ProfileGroupBase hoặc cài đặt Trình tạo Hồ sơ Web (WPB) có thể tạo lớp cho bạn từ định nghĩa trong Web.Config. Tôi đã sử dụng WPB trong một thời gian và cho đến nay nó đã làm được những gì mong đợi về nó. Nếu bạn có nhiều thuộc tính, sử dụng WPB có thể tiết kiệm kha khá thời gian.
  • Đảm bảo rằng kết nối với cơ sở dữ liệu được định cấu hình đúng trong Web.Config.
  • Bây giờ bạn được thiết lập để tạo một phiên bản của lớp hồ sơ của bạn (trong bộ điều khiển)
  • Bạn có thể sẽ cần các giá trị thuộc tính hồ sơ trong chế độ xem của mình. Tôi muốn chuyển đối tượng hồ sơ cùng với chế độ xem (không phải thuộc tính riêng lẻ).

3

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ả.


3
System.Web.Profile - Đây là một số mã mẫu: weblogs.asp.net/jgalloway/archive/2008/01/19/…
nshaw


2

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: - ProfilePropertyWeb.config

Bây giờ, hãy viết đoạn mã sau: -

Mã đằng sau thuộc tính hồ sơ

Biên dịch và chạy mã. Bạn sẽ nhận được kết quả sau: -

Đầu ra


1

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ể

  • sử dụng trình tạo hồ sơ web
  • xóa tất cả các dấu vết của nó!
  • tiếp tục sử dụng lớp Hồ sơ đã tạo

HOẶC (chưa được kiểm tra nhưng có thể chỉ hoạt động)

  • tạo một dự án trang web
  • tạo yếu tố của bạn
  • chụp các lớp được tạo ra và sao chép nó qua web của bạn dự án dự án

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


1

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>

<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ũ ...


0

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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.