Как назначить значения профиля?


110

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

Ответы:


179

Сегодня у меня была такая же проблема, и я многому научился.

В Visual Studio есть два типа проектов - «Проекты веб-сайтов» и «Проекты веб-приложений». По причинам, которые для меня являются полной загадкой, проекты веб-приложений не могут использовать профиль.напрямую ... строго типизированный класс не создается для вас волшебным образом из файла Web.config, поэтому вам придется использовать свой собственный.

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

У вас есть два варианта:

(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 просмотров страниц в день. Когда я писал это, я работал над другим проектом.
Джоэл Спольски

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? Вы не можете использовать «Profile.MyProperty», вы должны использовать свой собственный доморощенный класс, который не настраивается на каждой странице так, как автоматически устанавливается Profile. Все это позволяет вам использовать функцию Save () без необходимости ее кодирования.
Mike K

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

2
Если вы случайно определите свойства профиля в веб-конфигурации <profile ..><properties><add name="..">как в классе AccountProfile, так и в классе 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();

Вышеупомянутое отлично работает, если вам удобно использовать динамические типы и вы не возражаете против отсутствия проверки во время компиляции и 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

Если вы создаете собственный класс профиля, как описал выше Джоэл, 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. К свойствам профиля нельзя получить доступ с помощью профиля. синтаксис, как указано выше, но может быть легко выполнен путем создания экземпляра 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

Если вы используете проект веб-приложения, вы не можете получить доступ к объекту Profile во время разработки прямо из коробки. Вот утилита, которая предположительно сделает это за вас: 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

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

Я реализовал его решение, работающее блестяще, кстати - 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.