จะกำหนดค่าโปรไฟล์ได้อย่างไร?


110

ฉันไม่รู้ว่าฉันขาดอะไรไป แต่ฉันเพิ่มคุณสมบัติของโปรไฟล์ในไฟล์ Web.config แต่ไม่สามารถเข้าถึงโปรไฟล์ได้ รายการในรหัสหรือสร้างโปรไฟล์ใหม่

คำตอบ:


179

วันนี้ฉันมีปัญหาเดียวกันและได้เรียนรู้มากมาย

Visual Studio มีโครงการสองประเภทคือ "โครงการเว็บไซต์" และ "โครงการแอปพลิเคชันบนเว็บ" ด้วยเหตุผลที่เป็นปริศนาสำหรับฉันโครงการ Web Application ไม่สามารถใช้โปรไฟล์ได้ โดยตรง ... คลาสที่พิมพ์ผิดไม่ได้สร้างขึ้นอย่างน่าอัศจรรย์สำหรับคุณจากไฟล์ Web.config ดังนั้นคุณต้องม้วนของคุณเอง

โค้ดตัวอย่างใน MSDN จะถือว่าคุณกำลังใช้ Web Site Project และพวกเขาบอกให้คุณเพิ่ม<profile>ส่วนให้กับคุณWeb.configและปาร์ตี้ด้วยProfile.คุณสมบัติแต่ใช้ไม่ได้ใน Web Application Projects

คุณมีสองทางเลือกในการหมุนของคุณเอง:

(1) ใช้สร้างเว็บส่วนตัว นี่คือเครื่องมือแบบกำหนดเองที่คุณเพิ่มลงใน Visual Studio ซึ่งสร้างออบเจ็กต์โปรไฟล์ที่คุณต้องการโดยอัตโนมัติจากนิยามของคุณใน Web.config

ฉันเลือกที่จะไม่ทำเช่นนี้เพราะฉันไม่ต้องการให้โค้ดของฉันขึ้นอยู่กับเครื่องมือพิเศษนี้ในการคอมไพล์ซึ่งอาจทำให้เกิดปัญหากับคนอื่นในขณะที่พวกเขาพยายามสร้างโค้ดของฉันโดยที่ไม่รู้ว่าพวกเขาต้องการเครื่องมือนี้

(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;

10
StackOverflow เองไม่ได้ใช้โปรไฟล์ รหัสนี้อาจไม่เร็วพอสำหรับไซต์ที่มีการดูหน้าเว็บ 1,000,000 ครั้งต่อวัน ฉันกำลังทำงานในโครงการอื่นเมื่อฉันเขียนสิ่งนี้
Joel Spolsky

1
เป็นความผิดของฉันเอง แต่ฉันพยายามอยู่พักหนึ่งกับการตั้งค่าคุณสมบัติหลังจากเรียก CurrentUser เนื่องจาก CurrentUser สร้างอินสแตนซ์และส่งคืนอินสแตนซ์ใหม่ทุกครั้งฉันขอแนะนำให้กำหนดเป็นวิธีการแทนได้หรือไม่ โดยไม่ต้องคิดฉันเขียนสิ่งนี้: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); ซึ่งไม่ได้ผล ควรเป็น: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "สนูปปี้"; currentProfile.OtherProperty = "เอบีซี"; currentProfile.Save ();
Jeremy Gruenwald

1
ประเภทนี้ไม่ได้เอาชนะจุดประสงค์ทั้งหมดของ Profile หรือ? คุณไม่สามารถใช้ "Profile.MyProperty" ได้คุณต้องใช้คลาสที่ปลูกเองตามบ้านซึ่งไม่ได้ตั้งค่าไว้ในทุกหน้าเหมือนที่ Profile เป็นอัตโนมัติ ทั้งหมดนี้ช่วยให้คุณใช้คุณสมบัติ Save () ได้โดยไม่ต้องเขียนโค้ด
Mike K

7
โครงการ Web Application ไม่สามารถใช้ Profile
Joel Spolsky

2
หากคุณกำหนดคุณสมบัติโปรไฟล์โดยไม่ได้ตั้งใจในการกำหนดค่าเว็บภายใต้<profile ..><properties><add name="..">เช่นเดียวกับในคลาส AccountProfile คุณจะได้รับ "คุณสมบัตินี้ได้รับการกำหนดแล้ว" แก้ไขได้อย่างง่ายดายโดยการลบคุณสมบัติใน web.config
Zachary Scott

17

โครงการแอปพลิเคชันเว็บยังคงสามารถใช้อ็อบเจ็กต์ 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();

ข้างต้นใช้งานได้ดีหากคุณสะดวกในการใช้ประเภทไดนามิกและไม่ต้องกังวลกับการขาดการตรวจสอบเวลาคอมไพล์และ Intellisense

หากคุณใช้สิ่งนี้กับ 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


ฉันไม่สามารถบันทึกโปรไฟล์ได้ ข้อผิดพลาดคือ: 'ProfileCommon' ไม่มีคำจำกัดความสำหรับ 'save'
Jimmy

2
@Salman: ProfileCommon มาจาก System.Web.Profile.ProfileBase ซึ่งมีเมธอด Save () โปรดตรวจสอบว่าการใช้อักษรตัวพิมพ์ใหญ่ของคุณถูกต้อง ดู: msdn.microsoft.com/en-us/library/…
colivier

13

สามารถใช้โปรไฟล์ในโครงการ Web Application ได้เช่นกัน คุณสมบัติสามารถกำหนดใน 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 Namespace ในการใช้คุณสมบัติเหล่านั้นของโปรไฟล์ให้ใช้ System.Web.Profile.ProfileBase Objects ไม่สามารถเข้าถึงคุณสมบัติโปรไฟล์ด้วยโปรไฟล์ ไวยากรณ์ตามที่กล่าวไว้ข้างต้น แต่สามารถทำได้อย่างง่ายดายโดยการสร้างอินสแตนซ์ 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();

1
ฉันไม่รู้ว่าทำไมถึงไม่ได้รับ 1,000 โหวต เป็นประโยชน์อย่างยิ่ง
pghcpa

ฉันเดาว่าไม่มีใครรบกวนการเลื่อนลงมาที่นี่ นี่คือทองคำขอบคุณ Bede! หลังจากบันทึกข้อมูลข้างต้นฉันสามารถเข้าถึงข้อมูลผู้ใช้ได้จากทุกที่เพียงแค่สร้างProfileBaseวัตถุใหม่และเรียกใช้GetPropertyValue("PropName")?
seebiscuit

น่าทึ่งนี่เป็นวิธีเดียวที่เหมาะกับฉัน Thans Bede
Emanuel Pirovano

ปัญหาแรกฉันจะใช้ get ในหน้าอื่นได้อย่างไร?
Emanuel Pirovano

8

เมื่อคุณสร้างโครงการเว็บไซต์ใหม่ใน Visual Studio วัตถุที่ส่งคืนจากโปรไฟล์จะถูกสร้างขึ้น (โดยอัตโนมัติ) ให้คุณ เมื่อคุณสร้างโครงการเว็บแอปพลิเคชันหรือโครงการ MVC คุณจะต้องม้วนของคุณเอง

นี่อาจจะฟังดูยากกว่าที่เป็นอยู่ คุณต้องดำเนินการดังต่อไปนี้:

  • สร้างฐานข้อมูลโดยใช้aspnet_regsql.exeเครื่องมือนี้ได้รับการติดตั้งพร้อมกับ. NET framework
  • เขียนคลาสที่มาจาก ProfileGroupBase หรือติดตั้ง Web Profile Builder (WPB) ที่สามารถสร้างคลาสให้คุณจากนิยามใน Web.Config ฉันใช้ WPB มาระยะหนึ่งแล้วจนถึงตอนนี้มันได้ทำตามที่คาดหวังไว้แล้ว หากคุณมีคุณสมบัติมากมายการใช้ WPB จะช่วยประหยัดเวลาได้ไม่น้อย
  • ตรวจสอบให้แน่ใจว่าการเชื่อมต่อกับฐานข้อมูลได้รับการกำหนดค่าอย่างเหมาะสมใน Web.Config
  • ตอนนี้คุณได้รับการตั้งค่าให้สร้างอินสแตนซ์ของคลาสโปรไฟล์ของคุณแล้ว (ในคอนโทรลเลอร์)
  • คุณอาจต้องใช้ค่าคุณสมบัติโปรไฟล์ในมุมมองของคุณ ฉันต้องการส่งต่อวัตถุโปรไฟล์ไปยังมุมมอง (ไม่ใช่คุณสมบัติแต่ละรายการ)

3

หากคุณกำลังใช้โปรเจ็กต์เว็บแอปพลิเคชันคุณจะไม่สามารถเข้าถึงออบเจ็กต์โปรไฟล์ได้เมื่อหมดเวลาออกแบบ นี่คือประโยชน์ที่คาดคะเนไม่ได้สำหรับคุณ: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx โดยส่วนตัวยูทิลิตี้นั้นทำให้เกิดข้อผิดพลาดในโปรเจ็กต์ของฉันดังนั้นฉันจึงต้องกลิ้งคลาสโปรไฟล์ของฉันเองเพื่อสืบทอดจาก ProfileBase มันไม่ยากที่จะทำเลย


3
System.Web.Profile - นี่คือตัวอย่างโค้ด: weblogs.asp.net/jgalloway/archive/2008/01/19/…
nshaw


2

ฉันยังพบปัญหาเดียวกัน แต่แทนที่จะสร้างคลาสที่สืบทอดมาจาก ProfileBase ฉันใช้ HttpContext

ระบุคุณสมบัติในไฟล์ web.config ดังนี้: - ProfilePropertyWeb.config

ตอนนี้เขียนรหัสต่อไปนี้: -

รหัสหลังคุณสมบัติโปรไฟล์

คอมไพล์และรันโค้ด คุณจะได้รับผลลัพธ์ดังต่อไปนี้: -

เอาต์พุต


1

ตัวสร้างโปรไฟล์เว็บการทำงานที่ดีสำหรับฉัน คลาสที่สร้างขึ้นมีมากกว่าที่อธิบายไว้ในโพสต์ของ Joel ไม่ว่ามันจำเป็นหรือมีประโยชน์จริงหรือไม่ฉันไม่รู้

อย่างไรก็ตามสำหรับผู้ที่มองหาวิธีง่ายๆในการสร้างคลาส แต่ไม่ต้องการให้มีการพึ่งพาเครื่องมือสร้างภายนอกคุณสามารถทำได้ตลอดเวลา

  • ใช้ตัวสร้างโปรไฟล์เว็บ
  • ลบร่องรอยทั้งหมด!
  • ใช้คลาสโปรไฟล์ที่สร้างขึ้นต่อไป

หรือ (ยังไม่ทดลอง แต่อาจใช้งานได้)

  • สร้างโครงการเว็บไซต์
  • สร้างองค์ประกอบของคุณ
  • สแน็ปชั้นสร้างและคัดลอกไปยังเว็บของคุณโครงการโครงการ

หากแนวทางที่สองนี้ได้ผลใครสามารถแจ้งให้เราทราบเพื่อใช้อ้างอิงในอนาคต


1

เพียงแค่ต้องการเพิ่มคำตอบของ 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(); }
        }
    }
}

ใช้งานได้เหมือนมีเสน่ห์ ...


0

โพสต์ที่ดี

เพียงแค่บันทึกไว้บน web.config หากคุณไม่ได้ระบุแอตทริบิวต์ที่สืบทอดมาในองค์ประกอบโปรไฟล์คุณจะต้องระบุคุณสมบัติโปรไฟล์ของแต่ละบุคคลภายในองค์ประกอบโปรไฟล์บน web.config ดังต่อไปนี้

 <properties>
    <clear/>
    <add name="property-name-1" />
    <add name="property-name-2" />
    ..........

 </properties>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.