Domanda

Non so cosa mi manca, ma ho aggiunto le proprietà del profilo nel file Web.config ma non riesco ad accedere al profilo. Elemento nel codice o creare un nuovo profilo.

È stato utile?

Soluzione

Oggi ho avuto lo stesso problema e ho imparato molto.

Esistono due tipi di progetti in Visual Studio: " Progetti per siti Web " e " Progetti di applicazioni Web. " Per ragioni che per me sono un mistero completo, i progetti di applicazioni Web non possono utilizzare Profilo. direttamente ... la classe fortemente tipizzata non viene generata magicamente per te dal file Web.config, quindi devi ruota il tuo.

Il codice di esempio in MSDN presuppone che tu stia utilizzando un progetto di sito Web e ti dice solo di aggiungere una sezione <profile> alla tua Web.config e festeggia con Profile. proprietà , ma ciò non funziona nei progetti di applicazioni Web.

Hai due possibilità di scegliere la tua:

(1) Utilizzare Web Profile Builder . Questo è uno strumento personalizzato che aggiungi a Visual Studio che genera automaticamente l'oggetto Profile necessario dalla tua definizione in Web.config.

Ho scelto di non farlo, perché non volevo che il mio codice dipendesse da questo strumento aggiuntivo da compilare, il che avrebbe potuto causare problemi a qualcun altro nel tentativo di creare il mio codice senza rendersi conto che avevano bisogno questo strumento.

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

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 chiamato 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;

Altri suggerimenti

I progetti di applicazioni Web possono comunque utilizzare l'oggetto ProfileCommon ma solo in fase di esecuzione. Il codice non viene generato nel progetto stesso, ma la classe viene 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 benissimo se ti senti a tuo agio con i tipi dinamici e non ti dispiace la mancanza di controllo in fase di compilazione e intellisense.

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

Se crei la tua classe di profilo assicurati di non specificare le proprietà del profilo nel file Web.config che hai già dichiarato nella tua classe di profilo personalizzata. Se lo fai ASP.Net genererà un errore del compilatore quando tenta di generare la classe ProfileCommon.

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

o Programmaticamente, crea la sezione del profilo creando un'istanza di ProfileSection e creando singole proprietà utilizzando ProfilePropertySettings e ProfilePropertySettingsColletion , tutti presenti nel sistema .Web.Configuration Namespace. Per usare quelle proprietà del profilo, usa gli oggetti System.Web.Profile.ProfileBase. Non è possibile accedere alle proprietà del profilo con profilo. sintassi come menzionato sopra, ma è possibile farlo facilmente creando un'istanza di ProfileBase e utilizzando SetPropertyValue (& Quot; PropertyName ") e GetPropertyValue {" Nome proprietà ") come segue:

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

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

Quando crei un nuovo progetto di sito Web in Visual Studio, l'oggetto che viene restituito dal profilo verrà (automaticamente) generato per te. Quando crei un progetto di applicazione Web o un progetto MVC, dovrai crearne uno tuo.

Probabilmente sembra più difficile di quanto non sia. Devi fare quanto segue:

  • Crea un database usando aspnet_regsql.exe Questo strumento è installato insieme al framework .NET.
  • Scrivi una classe che deriva da ProfileGroupBase o installa Web Profile Builder (WPB) che può generare la classe per te dalla definizione in Web.Config. Ho usato WPB per un po 'e fino ad ora ha fatto quello che ci si aspetta da esso. Se hai molte proprietà, l'uso di WPB può farti risparmiare un bel po 'di tempo.
  • Assicurarsi che la connessione al database sia configurata correttamente in Web.Config.
  • Ora sei pronto per creare un'istanza della classe del tuo 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 alle singole proprietà).

Se si utilizza un progetto di applicazione Web, non è possibile accedere all'oggetto Profilo 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, così ho finito col rotolare la mia classe di profilo per ereditare da ProfileBase. Non è stato affatto difficile da fare.

Procedura dettagliata MSDN per la creazione di una classe personalizzata (metodo di Joel a.k.a.):
http://msdn.microsoft.com/en-us/magazine/cc163624. aspx

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

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

Ora scrivi il seguente codice: -

Codice dietro le propriet&agrave; del profilo

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

Output

Il Web Profile Builder ha funzionato perfettamente per me. La classe che ha generato ha molto di più rispetto a quanto descritto dal post di Joel. Non so se sia effettivamente necessario o utile.

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

  • usa il generatore di profili web
  • cancellane ogni traccia!
  • continua a utilizzare la classe di profilo generata

OPPURE (non testato ma potrebbe funzionare)

  • crea un sito progetto
  • web
  • crea il tuo elemento
  • scatta la classe generata e copiarla sul tuo progetto progetto

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

Voglio solo aggiungere alla risposta di Joel Spolsky

Ho implementato la sua soluzione, lavorando brillantemente tra Cudos!

Per chiunque desideri ottenere un profilo utente che non sia l'utente che ho effettuato l'accesso 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 ...

Ottimo post,

Solo una nota sul web.config se non si specifica l'attributo ereditario nell'elemento profilo dovrai specificare ogni proprietà del profilo individuale all'interno del profilo elemento sul web.config come di seguito

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

 </properties>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top