Come assegnare i valori del profilo?


110

Non so cosa mi manchi, ma ho aggiunto le proprietà del profilo nel file Web.config ma non riesco ad accedere al profilo. Inserisci un elemento nel codice o crea un nuovo profilo.

Risposte:


179

Oggi ho avuto lo stesso problema e ho imparato molto.

Esistono due tipi di progetto in Visual Studio: "Progetti sito Web" e "Progetti applicazione Web". Per motivi che per me sono un mistero completo, i progetti di applicazioni Web non possono utilizzare il profilo. direttamente ... la classe fortemente tipizzata non viene generata magicamente per te dal file Web.config, quindi devi lanciarne una tua.

Il codice di esempio in MSDN presuppone che si sta utilizzando un Sito Web del progetto, e ti dicono solo di aggiungere una <profile>sezione per la vostra Web.confige festa con Profile.proprietà , ma questo non funziona in Web progetti di applicazioni.

Hai due scelte per rotolare il tuo:

(1) Utilizza il Web Profile Builder . Si tratta di uno strumento personalizzato aggiunto a Visual Studio che genera automaticamente l'oggetto Profile necessario dalla definizione in Web.config.

Ho scelto di non farlo, perché non volevo che il mio codice dipendesse da questo strumento aggiuntivo per la compilazione, il che avrebbe potuto causare problemi a qualcun altro lungo la linea quando hanno provato a costruire il mio codice senza rendersi conto che avevano bisogno di questo strumento.

(2) Crea la tua classe che deriva da ProfileBaseper rappresentare il tuo profilo personalizzato. Questo è più facile di quanto sembri. Ecco un esempio molto semplice che aggiunge un campo di profilo stringa "FullName":

Nel tuo web.config:

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

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

</profile>

In un file denominato 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
    }
}

Per impostare un valore di profilo:

AccountProfile.CurrentUser.FullName = "Snoopy";

Per ottenere un valore di profilo

string x = AccountProfile.CurrentUser.FullName;

10
StackOverflow stesso non utilizza i profili. Questo codice probabilmente non è abbastanza veloce per un sito con 1.000.000 di visualizzazioni di pagina al giorno. Stavo lavorando a un altro progetto quando ho scritto questo.
Joel Spolsky

1
È colpa mia, ma ho lottato per un po 'con l'impostazione delle proprietà dopo aver chiamato CurrentUser. Poiché CurrentUser crea un'istanza e restituisce una nuova istanza ogni volta, posso suggerire di definirla invece come metodo? Senza pensarci, ho scritto questo: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); che non funziona. Dovrebbe essere: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "Snoopy"; currentProfile.OtherProperty = "ABC"; currentProfile.Save ();
Jeremy Gruenwald

1
Questo tipo di sconfitta non sconfigge l'intero scopo di Profile? Non puoi usare "Profile.MyProperty", devi usare la tua classe cresciuta in casa, che non è impostata su ogni pagina come lo è automaticamente Profile. Tutto questo ti consente di utilizzare la funzione Save () senza doverla codificare.
Mike K

7
I progetti di applicazioni Web non possono utilizzare il profilo.
Joel Spolsky

2
Se definisci accidentalmente le proprietà del profilo nella configurazione web sotto <profile ..><properties><add name="..">così come nella classe AccountProfile, otterrai un messaggio "Questa proprietà è già stata definita", facilmente risolvibile rimuovendo le proprietà nel web.config.
Zachary Scott

17

I progetti di applicazioni Web possono ancora utilizzare l'oggetto ProfileCommon ma solo in fase di esecuzione. Il codice per esso non viene generato nel progetto stesso, ma la classe è generata da ASP.Net ed è presente in fase di esecuzione.

Il modo più semplice per arrivare all'oggetto è usare un tipo dinamico come mostrato di seguito.

Nel file Web.config dichiarare le proprietà del profilo:

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

Quindi per accedere alle proprietà:

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

Per salvare le modifiche alle proprietà del profilo:

profile.Save();

Quanto sopra funziona bene se ti senti a tuo agio nell'usare i tipi dinamici e non ti importa della mancanza di controllo in fase di compilazione e intellisense.

Se lo usi con ASP.Net MVC devi fare del lavoro aggiuntivo se passi l'oggetto profilo dinamico alle tue viste poiché i metodi helper HTML non funzionano bene con oggetti "modello" che sono dinamici. Dovrai assegnare le proprietà del profilo alle variabili tipizzate staticamente prima di passarle ai metodi di supporto 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 crei una classe di profilo personalizzata, come Joel descritto sopra, ASP.Net genererà comunque la classe ProfileCommon ma erediterà dalla tua classe di profilo personalizzato. Se non specifichi una classe di profilo personalizzata, ProfileCommon erediterà da System.Web.Profile.ProfileBase.

Se crei la tua classe profilo, assicurati di non specificare le proprietà del profilo nel file Web.config che hai già dichiarato nella classe del profilo personalizzato. Se si esegue ASP.Net, verrà visualizzato un errore del compilatore quando si tenta di generare la classe ProfileCommon.


non riesco a salvare il profilo. l'errore è: "ProfileCommon" non contiene una definizione per "salva"
Jimmy

2
@Salman: ProfileCommon è derivato da System.Web.Profile.ProfileBase che ha un metodo Save (). Verifica che le maiuscole siano corrette. Vedi: msdn.microsoft.com/en-us/library/...
colivier

13

Il profilo può essere utilizzato anche nei progetti di applicazioni Web. Le proprietà possono essere definite in Web.config in fase di progettazione oa livello di programmazione. In 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>

oppure A livello di codice , creare la sezione del profilo creando un'istanza di ProfileSection e creando singole proprietà utilizzando ProfilePropertySettings e ProfilePropertySettingsColletion , tutti nello spazio dei nomi System.Web.Configuration. Per utilizzare queste proprietà del profilo, utilizzare System.Web.Profile.ProfileBase Objects. Non è possibile accedere alle proprietà del profilo con il profilo. sintassi come menzionato sopra, ma può essere facilmente eseguito creando un'istanza di ProfileBase e utilizzando SetPropertyValue (" PropertyName ") e GetPropertyValue {" PropertyName ") come segue:

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

oppure per accedere al profilo dell'utente corrente:

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
Non so perché questo non abbia ottenuto 1000 voti. È estremamente utile.
pghcpa

Immagino che nessuno si preoccupi di scorrere qui. Questo è Gold, grazie Bede! Dopo aver salvato i dati di cui sopra, posso accedere ai dati utente da qualsiasi luogo semplicemente creando un nuovo ProfileBaseoggetto e invocando GetPropertyValue("PropName")?
seebiscuit

Fantastico, questo è l'unico modo che funziona per me. Thans Bede
Emanuel Pirovano

Primo problema, come posso utilizzare il get in un'altra pagina?
Emanuel Pirovano

8

Quando crei un nuovo progetto di sito Web in Visual Studio, l'oggetto restituito da Profile verrà generato (automaticamente) per te. Quando crei un progetto di applicazione Web o un progetto MVC, dovrai eseguire il rollio personale.

Questo probabilmente suona più difficile di quello che è. Devi fare quanto segue:

  • Creare un database utilizzando aspnet_regsql.exe Questo strumento viene installato insieme al framework .NET.
  • Scrivi una classe che derivi da ProfileGroupBase o installa il Web Profile Builder (WPB) che può generare la classe per te dalla definizione in Web.Config. Uso WPB da un po 'di tempo e fino ad ora ha fatto ciò che ci si aspettava da esso. Se hai molte proprietà, l'utilizzo di WPB può far risparmiare un bel po 'di tempo.
  • Assicurati che la connessione al database sia configurata correttamente in Web.Config.
  • Ora sei pronto per creare un'istanza della tua classe profilo (nel controller)
  • Probabilmente avrai bisogno dei valori delle proprietà del profilo nelle tue viste. Mi piace passare l'oggetto profilo stesso alla vista (non le proprietà individuali).

3

Se si utilizza un progetto di applicazione Web, non è possibile accedere all'oggetto Profile in fase di progettazione immediatamente. Ecco un'utilità che presumibilmente lo fa per te: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Personalmente, quell'utilità ha causato un errore nel mio progetto, quindi ho finito per eseguire il rollio della mia classe di profilo per ereditare da ProfileBase. Non è stato affatto difficile.


3
System.Web.Profile - Ecco un po 'di codice di esempio: weblogs.asp.net/jgalloway/archive/2008/01/19/…
nshaw


2

Stavo anche affrontando lo stesso problema. Ma invece di creare una classe che eredita da ProfileBase, ho usato HttpContext.

Specificare le proprietà nel file web.config come segue: - ProfilePropertyWeb.config

Ora scrivi il seguente codice: -

Codice dietro le proprietà del profilo

Compila ed esegui il codice. Otterrai il seguente output: -

Produzione


1

Il Web Profile Builder ha funzionato alla grande per me. La classe che ha generato contiene molto di più rispetto a quanto descritto nel post di Joel. Se sia effettivamente necessario o utile non lo so.

Ad ogni modo per coloro che cercano un modo semplice per generare la classe, ma non vogliono avere una dipendenza da uno strumento di compilazione esterno, puoi sempre

  • utilizzare il generatore di profili web
  • cancella ogni traccia di esso!
  • continuare a utilizzare la classe Profile generata

OPPURE (non testato ma potrebbe funzionare)

  • creare un progetto di sito web
  • crea il tuo elemento
  • scattare la classe generata e copiarlo sopra al vostro web del progetto del progetto

se questo secondo approccio funziona, qualcuno può farmelo sapere per riferimento futuro


1

Voglio solo aggiungere alla risposta di Joel Spolsky

Ho implementato la sua soluzione, lavorando brillantemente btw - Cudos!

Per chiunque desideri ottenere un profilo utente che non sia l'utente connesso che ho usato:

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 poi la mia classe personalizzata:

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

Funziona come un fascino ...


0

Ottimo post,

Solo una nota sul web.config se non specifichi l'attributo inherit nell'elemento del profilo dovrai specificare ogni proprietà del profilo individuale all'interno dell'elemento del profilo sul web.config come sotto

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

 </properties>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.