Réponses:
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 ProfileBase
pour 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;
<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.
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.
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();
ProfileBase
objet et en appelant GetPropertyValue("PropName")
?
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:
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.
Procédure pas à pas MSDN pour créer une classe personnalisée (méthode de Joel):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
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: -
Maintenant, écrivez le code suivant: -
Compilez et exécutez le code. Vous obtiendrez la sortie suivante: -
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
OU (non testé mais peut simplement fonctionner)
si cette deuxième approche fonctionne, quelqu'un peut-il me le faire savoir pour référence future
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 ...
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>