Antworten:
Ich hatte heute das gleiche Problem und habe viel gelernt.
In Visual Studio gibt es zwei Arten von Projekten: "Website-Projekte" und "Webanwendungsprojekte". Aus Gründen, die mir ein Rätsel sind, können Webanwendungsprojekte Profile nicht verwenden . direkt ... die stark typisierte Klasse wird nicht auf magische Weise aus der Datei Web.config für Sie generiert, daher müssen Sie Ihre eigene rollen.
Der Beispielcode in MSDN setzt voraus, dass Sie ein Website-Projekt verwenden, und fordert Sie auf, nur einen <profile>
Abschnitt zu Ihrer Web.config
und der Party mit Profile.
Eigenschaft hinzuzufügen , dies funktioniert jedoch nicht in Webanwendungsprojekten.
Sie haben zwei Möglichkeiten, Ihre eigenen zu würfeln:
(1) Verwenden Sie den Web Profile Builder . Dies ist ein benutzerdefiniertes Tool, das Sie zu Visual Studio hinzufügen und das automatisch das benötigte Profilobjekt aus Ihrer Definition in Web.config generiert.
Ich habe mich dagegen entschieden, weil ich nicht wollte, dass mein Code von diesem zusätzlichen Tool zum Kompilieren abhängt, was zu Problemen für andere Personen führen könnte, die versucht haben, meinen Code zu erstellen, ohne zu bemerken, dass sie dieses Tool benötigen.
(2) Erstellen Sie Ihre eigene Klasse, aus ProfileBase
der Ihr benutzerdefiniertes Profil hervorgeht. Das ist einfacher als es scheint. Hier ist ein sehr sehr einfaches Beispiel, das ein Zeichenfolgenprofilfeld "FullName" hinzufügt:
In Ihrer web.config:
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>
In einer Datei namens 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
}
}
So legen Sie einen Profilwert fest:
AccountProfile.CurrentUser.FullName = "Snoopy";
Um einen Profilwert zu erhalten
string x = AccountProfile.CurrentUser.FullName;
<profile ..><properties><add name="..">
in der Webkonfiguration unter sowie in der AccountProfile-Klasse definieren, erhalten Sie die Meldung "Diese Eigenschaft wurde bereits definiert", die durch Entfernen der Eigenschaften in der web.config leicht behoben werden kann.
Webanwendungsprojekte können das ProfileCommon-Objekt weiterhin verwenden, jedoch nur zur Laufzeit. Der Code dafür wird einfach nicht im Projekt selbst generiert, sondern die Klasse wird von ASP.Net generiert und ist zur Laufzeit vorhanden.
Der einfachste Weg, um zum Objekt zu gelangen, ist die Verwendung eines dynamischen Typs, wie unten gezeigt.
Deklarieren Sie in der Datei Web.config die Profileigenschaften:
<profile ...
<properties>
<add name="GivenName"/>
<add name="Surname"/>
</properties>
Um dann auf die Eigenschaften zuzugreifen:
dynamic profile = ProfileBase.Create(Membership.GetUser().UserName);
string s = profile.GivenName;
profile.Surname = "Smith";
So speichern Sie Änderungen an Profileigenschaften:
profile.Save();
Das Obige funktioniert gut, wenn Sie mit dynamischen Typen vertraut sind und die fehlende Überprüfung der Kompilierungszeit und Intellisense nicht stören.
Wenn Sie dies mit ASP.Net MVC verwenden, müssen Sie zusätzliche Arbeit leisten, wenn Sie das dynamische Profilobjekt an Ihre Ansichten übergeben, da die HTML-Hilfsmethoden mit "Modell" -Objekten, die dynamisch sind, nicht gut funktionieren. Sie müssen statisch typisierten Variablen Profileigenschaften zuweisen, bevor Sie sie an HTML-Hilfsmethoden übergeben.
// 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
Wenn Sie eine benutzerdefinierte Profilklasse erstellen, wie Joel oben beschrieben hat, generiert ASP.Net weiterhin die ProfileCommon-Klasse, erbt jedoch von Ihrer benutzerdefinierten Profilklasse. Wenn Sie keine benutzerdefinierte Profilklasse angeben, erbt ProfileCommon von System.Web.Profile.ProfileBase.
Wenn Sie eine eigene Profilklasse erstellen, stellen Sie sicher, dass Sie in der Datei Web.config keine Profileigenschaften angeben, die Sie bereits in Ihrer benutzerdefinierten Profilklasse deklariert haben. Wenn Sie dies tun, gibt ASP.Net einen Compilerfehler aus, wenn versucht wird, die ProfileCommon-Klasse zu generieren.
Das Profil kann auch in Webanwendungsprojekten verwendet werden. Die Eigenschaften können zur Entwurfszeit oder programmgesteuert in Web.config definiert werden. 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>
oder programmatisch, erstellen Sie den Profilabschnitt durch ein Instanziierung Profile und individuelle Eigenschaften zu schaffen unter Verwendung von ProfilePropertySettings und ProfilePropertySettingsColletion , von denen alle in System.Web.Configuration Namespace. Verwenden Sie System.Web.Profile.ProfileBase-Objekte, um diese Eigenschaften des Profils zu verwenden. Auf die Profileigenschaften kann nicht mit Profil zugegriffen werden . Syntax wie oben erwähnt, kann jedoch einfach durch Instanziieren einer ProfileBase und Verwenden von SetPropertyValue (" PropertyName ") und GetPropertyValue (" PropertyName ") wie folgt durchgeführt werden:
ProfileBase curProfile = ProfileBase.Create("MyName");
oder um auf das Profil des aktuellen Benutzers zuzugreifen:
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
Objekt erstelle und aufrufe GetPropertyValue("PropName")
.
Wenn Sie in Visual Studio ein neues Websiteprojekt erstellen, wird das von Profile zurückgegebene Objekt (automatisch) für Sie generiert. Wenn Sie ein Webanwendungsprojekt oder ein MVC-Projekt erstellen, müssen Sie Ihr eigenes rollen.
Das klingt wahrscheinlich schwieriger als es ist. Sie müssen Folgendes tun:
Wenn Sie ein Webanwendungsprojekt verwenden, können Sie zur Entwurfszeit nicht sofort auf das Profilobjekt zugreifen. Hier ist ein Dienstprogramm, das es angeblich für Sie erledigt: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Persönlich verursachte dieses Dienstprogramm einen Fehler in meinem Projekt, sodass ich meine eigene Profilklasse rollte, um sie von ProfileBase zu erben. Es war überhaupt nicht schwer zu tun.
MSDN-exemplarische Vorgehensweise zum Erstellen einer benutzerdefinierten Klasse (auch bekannt als Joels Methode):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
Ich habe auch das gleiche Problem durchlaufen. Aber anstatt eine Klasse zu erstellen, die von ProfileBase erbt, habe ich den HttpContext verwendet.
Geben Sie die Eigenschaften in der Datei web.config wie folgt an: -
Schreiben Sie nun den folgenden Code: -
Kompilieren Sie den Code und führen Sie ihn aus. Sie erhalten folgende Ausgabe: -
Der Web Profile Builder hat bei mir hervorragend funktioniert. Die Klasse, die es generiert hat, enthält viel mehr als in Joels Beitrag beschrieben. Ob es tatsächlich benötigt oder nützlich ist, weiß ich nicht.
Auf jeden Fall für diejenigen, die nach einer einfachen Möglichkeit suchen, die Klasse zu generieren, aber keine externe Build-Tool-Abhängigkeit haben möchten, die Sie immer haben können
ODER (ungetestet, funktioniert aber möglicherweise nur)
Wenn dieser zweite Ansatz funktioniert, kann mich jemand zum späteren Nachschlagen informieren
Ich möchte nur Joel Spolskys Antwort hinzufügen
Ich habe seine Lösung implementiert und übrigens hervorragend gearbeitet - Cudos!
Für alle, die ein Benutzerprofil erhalten möchten, das nicht der angemeldete Benutzer ist, den ich verwendet habe:
web.config:
<connectionStrings>
<clear />
<add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" />
</connectionStrings>
und
<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/>
</providers>
Und dann meine benutzerdefinierte Klasse:
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(); }
}
}
}
Klappt wunderbar...
Guter Eintrag,
Nur ein Hinweis in der web.config Wenn Sie das ererbte Attribut im Profilelement nicht angeben, müssen Sie jede einzelne Profileigenschaft innerhalb des Profilelements in der web.config wie folgt angeben
<properties>
<clear/>
<add name="property-name-1" />
<add name="property-name-2" />
..........
</properties>