Як призначити значення профілю?


110

Я не знаю, чого мені не вистачає, але я додав властивості профілю у файл Web.config, але не можу отримати доступ до профілю. Пункт в коді або створити новий профіль.

Відповіді:


179

У мене була така ж проблема і сьогодні, і я багато чому навчився.

У Visual Studio є два види проекту - "Проекти веб-сайтів" та "Проекти веб-додатків". З причин, які є для мене цілковитою загадкою, Проекти веб-додатків не можуть використовувати профіль. безпосередньо ... сильно набраний клас не магічно створюється для вас з файлу Web.config, тому вам доведеться прокрутити свій власний.

Зразок коду в MSDN передбачає, що ви використовуєте проект веб-сайту, і вони говорять вам просто додати <profile>розділ до вашого Web.configі учасника з Profile.власністю , але це не працює в проектах веб-додатків.

У вас є два варіанти:

(1) Скористайтеся програмою Web Profile Builder . Це спеціальний інструмент, який ви додаєте до 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 переглядів сторінок на день. Коли я писав це, я працював над іншим проектом.
Джоель Спольський

1
Це моя власна вина, але я досить довго боровся з налаштуванням властивостей після виклику CurrentUser. Оскільки CurrentUser створює і повертає новий примірник кожен раз, чи можу я запропонувати визначити його як метод? Не замислюючись, я написав це: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); яка не працює. Це має бути: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "Снупі"; currentProfile.OtherProperty = "ABC"; currentProfile.Save ();
Джеремі Грюнвальд

1
Хіба цей спосіб не переможе цілі Профілю? Ви не можете використовувати "Profile.MyProperty", ви повинні використовувати власний домашній клас, який налаштовано не на кожній сторінці так, як автоматично працює профіль. Все це дозволяє вам використовувати функцію Save () без кодування.
Майк К

7
Проекти веб-додатків не можуть використовувати профіль.
Джоель Спольський

2
Якщо ви випадково визначите властивості профілю в веб-конфігурації <profile ..><properties><add name="..">, а також у класі AccountProfile, ви отримаєте "Це властивість уже визначено", легко виправити, видаливши властивості в web.config.
Захарі Скотт

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

Вищезазначене працює добре, якщо вам зручно використовувати динамічні типи і не заважайте на відсутність перевірки часу компіляції та інтелігенції.

Якщо ви використовуєте це з 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

Якщо ви створюєте спеціальний клас профілю, як описано вище Джоелем, ASP.Net все одно генерує клас ProfileCommon, але він успадковуватиметься від вашого спеціального профілю профілю. Якщо ви не вказали спеціальний клас профілю, профіль ProfileCommon успадкує від System.Web.Profile.ProfileBase.

Якщо ви створюєте свій власний клас профілю, переконайтеся, що ви не вказали властивості профілю у файлі Web.config, який ви вже декларували у власному класі профілю. Якщо ви зробите ASP.Net, він видасть помилку компілятора при спробі генерування класу ProfileCommon.


я не можу зберегти профіль. помилка така: 'ProfileCommon' не містить визначення для 'зберегти'
Джиммі

2
@Salman: ProfileCommon походить від System.Web.Profile.ProfileBase, який має метод Save (). Перевірте, чи правильно написана ваша література. Дивіться: msdn.microsoft.com/en-us/library/…
colivier

13

Профіль можна використовувати і в проектах веб-додатків. Властивості можна визначити в 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 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
Я не знаю, чому за це не було 1000 голосів. Це надзвичайно корисно.
pghcpa

Я думаю, ніхто тут не заважає прокручуватися. Це Золото, дякую Беде! Після збереження даних, наведених вище, я можу отримати доступ до даних користувача з будь-якого місця, просто створивши новий ProfileBaseоб’єкт і посилаючись на нього GetPropertyValue("PropName")?
seebiscuit

Дивовижно, це єдиний спосіб, який працює для мене. Танс Беде
Емануель Піровано

Перша проблема, як я можу використати get на іншій сторінці?
Емануель Піровано

8

Коли ви створюєте новий проект веб-сайту у Visual Studio, об’єкт, який повертається з профілю, буде (автоматично) генерований для вас. Коли ви створюєте проект веб-додатків або проект MVC, вам доведеться прокрутити свій власний.

Це, мабуть, звучить складніше, ніж це є. Вам потрібно зробити наступне:

  • Створіть базу даних, використовуючи aspnet_regsql.exe Цей інструмент встановлюється разом із .NET рамкою.
  • Напишіть клас, що походить від 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

Інструмент веб-профілів для мене відмінно працював. Клас, який він створив, містить у собі набагато більше, ніж описано у публікації Джоела. Незалежно від того, потрібна вона чи корисна, чи не знаю я.

У будь-якому випадку для тих, хто шукає простий спосіб генерувати клас, але не бажаючи мати зовнішню залежність від інструменту побудови, ви завжди можете

  • використовувати веб-конструктор профілів
  • видалити всі його сліди!
  • продовжуйте використовувати створений клас профілю

АБО (не перевірено, але може просто працювати)

  • створення веб - сайту проекту
  • створити свій елемент
  • оснастіть створений клас та скопіюйте його у проект свого веб- проекту

якщо цей другий підхід спрацює, може хтось повідомив мене для подальшого ознайомлення


1

Просто хочу додати відповідь Джоела Спольського

Я реалізував його рішення, працюючи блискуче btw - 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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.