Como atribuir valores de Perfil?

110

Não sei o que estou perdendo, mas adicionei propriedades de Perfil ao arquivo Web.config, mas não consigo acessar Perfil. Item no código ou crie um novo perfil.

zsharp
fonte

Respostas:

179

Tive o mesmo problema hoje e aprendi muito.

Existem dois tipos de projeto no Visual Studio - "Projetos de sites" e "Projetos de aplicativos da Web". Por motivos que são um mistério para mim, os Projetos de aplicativos da Web não podem usar o Perfil. diretamente ... a classe fortemente tipada não é gerada magicamente para você a partir do arquivo Web.config, portanto, você deve lançar a sua própria.

O código de exemplo MSDN assume que você está usando um projeto Web Site, e eles dizem que você acabou de adicionar uma <profile>seção para o seu Web.confige festa com Profile.propriedade , mas isso não funcionar em projetos de aplicativos da Web.

Você tem duas opções para fazer o seu próprio:

(1) Use o Web Profile Builder . Esta é uma ferramenta personalizada que você adiciona ao Visual Studio que gera automaticamente o objeto Perfil de que você precisa de sua definição em Web.config.

Decidi não fazer isso, porque não queria que meu código dependesse dessa ferramenta extra para compilar, o que poderia ter causado problemas para outra pessoa no futuro, quando tentasse construir meu código sem perceber que precisava dessa ferramenta.

(2) Faça sua própria classe derivada de ProfileBasepara representar seu perfil personalizado. Isso é mais fácil do que parece. Aqui está um exemplo muito simples que adiciona um campo de perfil de string "FullName":

Em seu web.config:

<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">

<providers>
     <clear />
     <add name="SqlProvider"
          type="System.Web.Profile.SqlProfileProvider"
          connectionStringName="sqlServerMembership" />
</providers>

</profile>

Em um arquivo chamado 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
    }
}

Para definir um valor de perfil:

AccountProfile.CurrentUser.FullName = "Snoopy";

Para obter um valor de perfil

string x = AccountProfile.CurrentUser.FullName;
Joel Spolsky
fonte
10
O próprio StackOverflow não usa perfis. Este código provavelmente não é rápido o suficiente para um site com 1.000.000 de visualizações de página por dia. Eu estava trabalhando em outro projeto quando escrevi isso.
Joel Spolsky
1
A culpa é minha, mas lutei por um bom tempo com a definição de propriedades depois de chamar CurrentUser. Uma vez que CurrentUser instancia e retorna uma nova instância a cada vez, posso sugerir defini-la como um método? Sem pensar, escrevi isso: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); o que não funciona. Deve ser: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "Snoopy"; currentProfile.OtherProperty = "ABC"; currentProfile.Save ();
Jeremy Gruenwald,
1
Isso não anula todo o propósito do Perfil? Você não pode usar "Profile.MyProperty", você tem que usar sua própria classe criada em casa, que não está configurada em todas as páginas da maneira que o Perfil é automaticamente. Tudo isso permite que você utilize o recurso Save () sem precisar codificá-lo.
Mike K
7
Projetos de aplicativos da Web não podem usar o Perfil.
Joel Spolsky
2
Se você definir acidentalmente propriedades de perfil na configuração da web <profile ..><properties><add name="..">, bem como na classe AccountProfile, você obterá uma mensagem "Esta propriedade já foi definida", facilmente corrigida removendo as propriedades no web.config.
Zachary Scott
17

Projetos de aplicativos da Web ainda podem usar o objeto ProfileCommon, mas apenas em tempo de execução. O código para isso não é gerado no próprio projeto, mas a classe é gerada por ASP.Net e está presente em tempo de execução.

A maneira mais simples de chegar ao objeto é usar um tipo dinâmico, conforme demonstrado abaixo.

No arquivo Web.config, declare as propriedades do perfil:

<profile ...
 <properties>
   <add name="GivenName"/>
   <add name="Surname"/>
 </properties>

Em seguida, para acessar as propriedades:

dynamic profile = ProfileBase.Create(Membership.GetUser().UserName);
string s = profile.GivenName;
profile.Surname = "Smith";

Para salvar as alterações nas propriedades do perfil:

profile.Save();

O procedimento acima funciona bem se você se sentir confortável usando tipos dinâmicos e não se importar com a falta de verificação em tempo de compilação e intellisense.

Se você usar isso com ASP.Net MVC, terá que fazer algum trabalho adicional se passar o objeto de perfil dinâmico para suas visualizações, pois os métodos auxiliares HTML não funcionam bem com objetos "modelo" que são dinâmicos. Você terá que atribuir propriedades de perfil a variáveis ​​digitadas estaticamente antes de passá-las para métodos auxiliares 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

Se você criar uma classe de perfil personalizado, como Joel descreveu acima, o ASP.Net ainda gerará a classe ProfileCommon, mas herdará de sua classe de perfil personalizado. Se você não especificar uma classe de perfil personalizado, ProfileCommon herdará de System.Web.Profile.ProfileBase.

Se você criar sua própria classe de perfil, certifique-se de não especificar propriedades de perfil no arquivo Web.config que você já declarou em sua classe de perfil personalizado. Se você fizer o ASP.Net, ocorrerá um erro do compilador ao tentar gerar a classe ProfileCommon.

Colivier
fonte
não consigo salvar o perfil. o erro é: 'ProfileCommon' não contém uma definição para 'salvar'
Jimmy,
2
@Salman: ProfileCommon é derivado de System.Web.Profile.ProfileBase, que possui um método Save (). Verifique se a capitalização está correta. Consulte: msdn.microsoft.com/en-us/library/…
colivier
13

O perfil também pode ser usado em projetos de aplicativos da Web. As propriedades podem ser definidas em Web.config em tempo de design ou programaticamente. Em 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>

ou Programaticamente, crie a seção de perfil instanciando um ProfileSection e criando propriedades individuais usando ProfilePropertySettings e ProfilePropertySettingsColletion , todos no namespace System.Web.Configuration. Para usar essas propriedades do perfil, use Objetos System.Web.Profile.ProfileBase. As propriedades do perfil não podem ser acessadas com o perfil. sintaxe conforme mencionado acima, mas pode ser facilmente feita instanciando um ProfileBase e usando SetPropertyValue (" PropertyName ") e GetPropertyValue {" PropertyName ") da seguinte maneira:

ProfileBase curProfile = ProfileBase.Create("MyName");

ou para acessar o perfil do usuário atual:

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();
Bede Amarasekara
fonte
1
Não sei por que não obteve 1000 votos. É extremamente útil.
pghcpa de
Acho que ninguém se incomoda em rolar aqui. Isso é ouro, obrigado Bede! Depois de salvar os dados acima, posso acessar os dados do usuário de qualquer lugar simplesmente criando um novo ProfileBaseobjeto e chamando GetPropertyValue("PropName")?
seebiscuit
Incrível, essa é a única maneira que funciona para mim. Thans Bede
Emanuel Pirovano
Primeiro problema, como posso usar o get em outra página?
Emanuel Pirovano
8

Quando você cria um novo projeto de site da Web no Visual Studio, o objeto que é retornado do Perfil será (automaticamente) gerado para você. Ao criar um projeto de aplicativo da Web ou um projeto MVC, você terá que lançar o seu próprio.

Isso provavelmente parece mais difícil do que é. Você precisa fazer o seguinte:

  • Crie um banco de dados usando aspnet_regsql.exe Esta ferramenta é instalada junto com o .NET framework.
  • Escreva uma classe que derive de ProfileGroupBase ou instale o Web Profile Builder (WPB) que pode gerar a classe para você a partir da definição em Web.Config. Eu uso o WPB há um tempo e até agora ele fez o que era esperado dele. Se você tiver muitas propriedades, usar o WPB pode economizar bastante tempo.
  • Certifique-se de que a conexão com o banco de dados esteja configurada corretamente no Web.Config.
  • Agora você está configurado para criar uma instância de sua classe de perfil (no controlador)
  • Você provavelmente precisará dos valores de propriedade do perfil em suas visualizações. Gosto de passar o próprio objeto de perfil para a visualização (não as propriedades individuais).
Capitão Sensível
fonte
3

Se você estiver usando um projeto de aplicativo da web, não poderá acessar o objeto Perfil no tempo de design pronto para uso. Aqui está um utilitário que supostamente faz isso para você: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Pessoalmente, esse utilitário causou um erro em meu projeto, então acabei lançando minha própria classe de perfil para herdar de ProfileBase. Não foi nada difícil de fazer.

nshaw
fonte
3
System.Web.Profile - Aqui está um exemplo de código: weblogs.asp.net/jgalloway/archive/2008/01/19/…
nshaw
2

Eu também estava passando pelo mesmo problema. Mas em vez de criar uma classe que herda de ProfileBase, usei o HttpContext.

Especifique as propriedades no arquivo web.config da seguinte maneira: - ProfilePropertyWeb.config

Agora, escreva o seguinte código: -

Código por trás das propriedades do perfil

Compile e execute o código. Você obterá a seguinte saída: -

Resultado

Anil Purswani
fonte
1

O Web Profile Builder funcionou muito bem para mim. A classe gerada tem muito mais do que descrito no post de Joel. Se é realmente necessário ou útil, não sei.

De qualquer forma, para quem procura uma maneira fácil de gerar a classe, mas não quer ter uma dependência de ferramenta de construção externa, você sempre pode

  • use o construtor de perfil da web
  • exclua todos os vestígios disso!
  • continue usando a classe de Perfil gerada

OU (não testado, mas pode funcionar)

  • criar um projeto de site
  • crie o seu elemento
  • Capture a classe gerada e copie-a para o seu projeto de projeto da web

se esta segunda abordagem funcionar, alguém pode me informar para referência futura

Simon_Weaver
fonte
1

Só quero acrescentar à resposta de Joel Spolsky

Implementei a solução dele, funcionando de forma brilhante btw - Cudos!

Para quem deseja obter um perfil de usuário que não seja o usuário conectado que usei:

web.config:

  <connectionStrings>
    <clear />
    <add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" />
  </connectionStrings>

e

<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true">
  <providers>
    <clear/>
    <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/>
  </providers>

E então minha classe personalizada:

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

Funciona como um encanto...

Arrebentar
fonte
0

Ótimo post,

Apenas uma observação sobre o web.config: se você não especificar o atributo inherit no elemento do perfil, você precisará especificar cada propriedade de perfil individual dentro do elemento do perfil no web.config conforme abaixo

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

 </properties>
indy
fonte