Respostas:
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.config
e 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 ProfileBase
para 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;
<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.
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.
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();
ProfileBase
objeto e chamando GetPropertyValue("PropName")
?
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:
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.
Passo a passo do MSDN para criar uma classe personalizada (também conhecido como método de Joel):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
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: -
Agora, escreva o seguinte código: -
Compile e execute o código. Você obterá a seguinte saída: -
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
OU (não testado, mas pode funcionar)
se esta segunda abordagem funcionar, alguém pode me informar para referência futura
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...
Ó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>