Comment attribuer des valeurs de profil?

110

Je ne sais pas ce qui me manque, mais j'ai ajouté des propriétés de profil dans le fichier Web.config mais je ne peux pas accéder au profil. Élément dans le code ou créer un nouveau profil.

zsharp
la source

Réponses:

179

J'ai eu le même problème aujourd'hui et j'ai beaucoup appris.

Il existe deux types de projets dans Visual Studio: «Projets de site Web» et «Projets d'application Web». Pour des raisons qui sont un mystère pour moi, les projets d'application Web ne peuvent pas utiliser Profile. directement ... la classe fortement typée n'est pas générée par magie pour vous à partir du fichier Web.config, vous devez donc lancer la vôtre.

L'exemple de code dans MSDN suppose que vous utilisez un projet de site Web, et ils vous disent simplement d'ajouter une <profile>section à votre propriétéWeb.config et partie avec , mais cela ne fonctionne pas dans les projets d'application Web.Profile.

Vous avez deux choix pour lancer le vôtre:

(1) Utilisez le générateur de profil Web . Il s'agit d'un outil personnalisé que vous ajoutez à Visual Studio qui génère automatiquement l'objet Profile dont vous avez besoin à partir de votre définition dans Web.config.

J'ai choisi de ne pas le faire, car je ne voulais pas que mon code dépende de cet outil supplémentaire pour la compilation, ce qui aurait pu causer des problèmes à quelqu'un d'autre sur toute la ligne quand ils ont essayé de construire mon code sans se rendre compte qu'ils avaient besoin de cet outil.

(2) Créez votre propre classe qui dérive de ProfileBasepour représenter votre profil personnalisé. C'est plus facile qu'il n'y paraît. Voici un exemple très très simple qui ajoute un champ de profil de chaîne "FullName":

Dans votre web.config:

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

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

</profile>

Dans un fichier appelé 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
    }
}

Pour définir une valeur de profil:

AccountProfile.CurrentUser.FullName = "Snoopy";

Pour obtenir une valeur de profil

string x = AccountProfile.CurrentUser.FullName;
Joël Spolsky
la source
10
StackOverflow lui-même n'utilise pas de profils. Ce code n'est probablement pas assez rapide pour un site avec 1 000 000 de pages vues par jour. Je travaillais sur un autre projet quand j'ai écrit ceci.
Joel Spolsky
1
C'est de ma faute, mais j'ai eu du mal pendant un certain temps à définir les propriétés après avoir appelé CurrentUser. Étant donné que CurrentUser instancie et retourne une nouvelle instance à chaque fois, puis-je suggérer de la définir comme une méthode à la place? Sans réfléchir, j'ai écrit ceci: AccountProfile.CurrentUser.FullName = "Snoopy"; AccountProfile.CurrentUser.OtherProperty = "ABC"; AccountProfile.CurrentUser.Save (); ce qui ne fonctionne pas. Il doit être: AccountProfile currentProfile = AccountProfile.CurrentUser; currentProfile.FullName = "Snoopy"; currentProfile.OtherProperty = "ABC"; currentProfile.Save ();
Jeremy Gruenwald du
1
Cela ne va-t-il pas à l'encontre de l'objectif de Profile? Vous ne pouvez pas utiliser "Profile.MyProperty", vous devez utiliser votre propre classe locale, qui n'est pas configurée sur chaque page comme Profile est automatiquement. Tout cela vous permet d'utiliser la fonction Save () sans avoir à la coder.
Mike K
7
Les projets d'application Web ne peuvent pas utiliser le profil.
Joel Spolsky
2
Si vous définissez accidentellement des propriétés de profil dans la configuration Web sous <profile ..><properties><add name="..">ainsi que dans la classe AccountProfile, vous obtiendrez un "Cette propriété a déjà été définie", facilement corrigée en supprimant les propriétés dans le fichier web.config.
Zachary Scott
17

Les projets d'application Web peuvent toujours utiliser l'objet ProfileCommon, mais uniquement lors de l'exécution. Le code correspondant n'est tout simplement pas généré dans le projet lui-même, mais la classe est générée par ASP.Net et est présente au moment de l'exécution.

Le moyen le plus simple d'accéder à un objet consiste à utiliser un type dynamique comme illustré ci-dessous.

Dans le fichier Web.config, déclarez les propriétés du profil:

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

Puis pour accéder aux propriétés:

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

Pour enregistrer les modifications apportées aux propriétés de profil:

profile.Save();

Ce qui précède fonctionne bien si vous êtes à l'aise avec l'utilisation des types dynamiques et que le manque de vérification à la compilation et d'intellisense ne vous dérange pas.

Si vous l'utilisez avec ASP.Net MVC, vous devez effectuer un travail supplémentaire si vous transmettez l'objet de profil dynamique à vos vues, car les méthodes d'assistance HTML ne fonctionnent pas bien avec les objets «modèle» qui sont dynamiques. Vous devrez affecter des propriétés de profil à des variables typées statiquement avant de les transmettre aux méthodes d'assistance 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

Si vous créez une classe de profil personnalisé, comme Joel l'a décrit ci-dessus, ASP.Net générera toujours la classe ProfileCommon, mais il héritera de votre classe de profil personnalisé. Si vous ne spécifiez pas de classe de profil personnalisée, ProfileCommon héritera de System.Web.Profile.ProfileBase.

Si vous créez votre propre classe de profil, assurez-vous de ne pas spécifier de propriétés de profil dans le fichier Web.config que vous avez déjà déclarées dans votre classe de profil personnalisé. Si vous le faites, ASP.Net donnera une erreur du compilateur lorsqu'il essaiera de générer la classe ProfileCommon.

colivier
la source
je ne peux pas enregistrer le profil. l'erreur est: 'ProfileCommon' ne contient pas de définition pour 'save'
Jimmy
2
@Salman: ProfileCommon est dérivé de System.Web.Profile.ProfileBase qui possède une méthode Save (). Veuillez vérifier que votre capitalisation est correcte. Voir: msdn.microsoft.com/en-us/library/…
colivier
13

Le profil peut également être utilisé dans les projets d'application Web. Les propriétés peuvent être définies dans Web.config au moment du design ou par programme. Dans 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 Par programme, créez la section de profil en instanciant un ProfileSection et en créant des propriétés individuelles à l'aide de ProfilePropertySettings et ProfilePropertySettingsColletion , qui se trouvent tous dans l'espace de noms System.Web.Configuration. Pour utiliser ces propriétés du profil, utilisez les objets System.Web.Profile.ProfileBase. Les propriétés du profil ne sont pas accessibles avec le profil. comme mentionné ci-dessus, mais peut être facilement réalisée en instanciant un ProfileBase et en utilisant SetPropertyValue (" PropertyName ") et GetPropertyValue {" PropertyName ") comme suit:

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

ou pour accéder au profil de l'utilisateur actuel:

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
la source
1
Je ne sais pas pourquoi cela n'a pas obtenu 1 000 votes. C'est extrêmement utile.
pghcpa
Je suppose que personne ne se soucie de faire défiler ici. C'est de l'or, merci Bede! Après avoir enregistré les données ci-dessus, je peux accéder aux données utilisateur de n'importe où en créant simplement un nouvel ProfileBaseobjet et en appelant GetPropertyValue("PropName")?
seebiscuit
Incroyable, c'est la seule façon qui fonctionne pour moi. Thans Bede
Emanuel Pirovano
Premier problème, comment puis-je utiliser le get dans une autre page?
Emanuel Pirovano
8

Lorsque vous créez un nouveau projet de site Web dans Visual Studio, l'objet renvoyé par Profile sera (automatiquement) généré pour vous. Lorsque vous créez un projet d'application Web ou un projet MVC, vous devrez créer le vôtre.

Cela semble probablement plus difficile qu'il ne l'est. Vous devez effectuer les opérations suivantes:

  • Créer une base de données en utilisant aspnet_regsql.exe Cet outil est installé avec le framework .NET.
  • Écrivez une classe qui dérive de ProfileGroupBase ou installez le générateur de profil Web (WPB) qui peut générer la classe pour vous à partir de la définition dans Web.Config. J'utilise WPB depuis un certain temps et jusqu'à présent, il a fait ce que l'on attend de lui. Si vous avez beaucoup de propriétés, l'utilisation de WPB peut vous faire gagner un peu de temps.
  • Assurez-vous que la connexion à la base de données est correctement configurée dans Web.Config.
  • Vous êtes maintenant prêt à créer une instance de votre classe de profil (dans le contrôleur)
  • Vous aurez probablement besoin des valeurs de propriété de profil dans vos vues. J'aime transmettre l'objet de profil lui-même à la vue (pas les propriétés individuelles).
Capitaine Sensible
la source
3

Si vous utilisez un projet d'application Web, vous ne pouvez pas accéder à l'objet Profile au moment du design prêt à l'emploi. Voici un utilitaire qui le fait supposément pour vous: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Personnellement, cet utilitaire a causé une erreur dans mon projet, alors j'ai fini par rouler ma propre classe de profil pour hériter de ProfileBase. Ce n'était pas du tout difficile à faire.

nshaw
la source
3
System.Web.Profile - Voici un exemple de code: weblogs.asp.net/jgalloway/archive/2008/01/19/…
nshaw
2

J'étais également confronté au même problème. Mais au lieu de créer une classe qui hérite de ProfileBase, j'ai utilisé le HttpContext.

Spécifiez les propriétés dans le fichier web.config comme suit: - ProfilePropertyWeb.config

Maintenant, écrivez le code suivant: -

Code derrière les propriétés du profil

Compilez et exécutez le code. Vous obtiendrez la sortie suivante: -

Production

Anil Purswani
la source
1

Le générateur de profil Web a très bien fonctionné pour moi. La classe qu'il a générée contient beaucoup plus que ce que décrit le message de Joel. Je ne sais pas si c'est réellement nécessaire ou utile.

Quoi qu'il en soit, pour ceux qui recherchent un moyen simple de générer la classe, mais ne veulent pas avoir une dépendance d'outil de construction externe, vous pouvez toujours

  • utiliser le générateur de profil Web
  • supprimez toute trace de celui-ci!
  • continuez à utiliser la classe Profile générée

OU (non testé mais peut simplement fonctionner)

  • créer un projet de site web
  • créez votre élément
  • capturez la classe générée et copiez-la dans votre projet de projet Web

si cette deuxième approche fonctionne, quelqu'un peut-il me le faire savoir pour référence future

Simon_Weaver
la source
1

Je veux juste ajouter à la réponse de Joel Spolsky

J'ai implémenté sa solution, en travaillant brillamment btw - Cudos!

Pour toute personne souhaitant obtenir un profil d'utilisateur qui n'est pas l'utilisateur connecté que j'ai utilisé:

web.config:

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

et

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

Et puis ma classe personnalisée:

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

Fonctionne comme un charme ...

Déchirer, foutre une branlée
la source
0

Très bonne publication,

Juste une note sur le web.config si vous ne spécifiez pas l'attribut inherit dans l'élément de profil, vous devrez spécifier chaque propriété de profil individuelle à l'intérieur de l'élément de profil sur le web.config comme ci-dessous

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

 </properties>
indy
la source