Відповіді:
У мене була така ж проблема і сьогодні, і я багато чому навчився.
У Visual Studio є два види проекту - "Проекти веб-сайтів" та "Проекти веб-додатків". З причин, які є для мене цілковитою загадкою, Проекти веб-додатків не можуть використовувати профіль. безпосередньо ... сильно набраний клас не магічно створюється для вас з файлу Web.config, тому вам доведеться прокрутити свій власний.
Зразок коду в MSDN передбачає, що ви використовуєте проект веб-сайту, і вони говорять вам просто додати <profile>
розділ до вашого Web.config
і учасника з Profile.
власністю , але це не працює в проектах веб-додатків.
У вас є два варіанти:
(1) Скористайтеся програмою Web Profile Builder . Це спеціальний інструмент, який ви додаєте до Visual Studio, який автоматично генерує необхідний вам профіль з вашого визначення в Web.config.
Я вирішив не робити цього, оскільки не хотів, щоб мій код залежав від цього додаткового інструменту для компіляції, що могло спричинити проблеми для когось іншого внизу лінії, коли він намагався створити мій код, не розуміючи, що їм потрібен цей інструмент.
(2) Створіть свій власний клас, який походить від того, ProfileBase
щоб представляти ваш спеціальний профіль. Це простіше, ніж здається. Ось дуже простий приклад, який додає поле профілю рядка "FullName":
У вашому web.config:
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>
У файлі під назвою 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
}
}
Щоб встановити значення профілю:
AccountProfile.CurrentUser.FullName = "Snoopy";
Щоб отримати значення профілю
string x = AccountProfile.CurrentUser.FullName;
<profile ..><properties><add name="..">
, а також у класі AccountProfile, ви отримаєте "Це властивість уже визначено", легко виправити, видаливши властивості в web.config.
Проекти веб-додатків все ще можуть використовувати об'єкт ProfileCommon, але лише під час виконання. Код для нього просто не генерується в самому проекті, але клас генерується ASP.Net і присутній під час виконання.
Найпростіший спосіб отримати об’єкт - це використовувати динамічний тип, як показано нижче.
У файлі Web.config заявіть про властивості профілю:
<profile ...
<properties>
<add name="GivenName"/>
<add name="Surname"/>
</properties>
Потім для доступу до властивостей:
dynamic profile = ProfileBase.Create(Membership.GetUser().UserName);
string s = profile.GivenName;
profile.Surname = "Smith";
Щоб зберегти зміни у властивостях профілю:
profile.Save();
Вищезазначене працює добре, якщо вам зручно використовувати динамічні типи і не заважайте на відсутність перевірки часу компіляції та інтелігенції.
Якщо ви використовуєте це з ASP.Net MVC, вам доведеться виконати додаткову роботу, якщо ви передаєте об’єкт динамічного профілю вашим переглядам, оскільки HTML-допоміжні методи не грають добре з "модельними" об'єктами, які є динамічними. Вам доведеться призначити властивості профілю статично набраним змінним, перш ніж передати їх до допоміжних методів 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
Якщо ви створюєте спеціальний клас профілю, як описано вище Джоелем, ASP.Net все одно генерує клас ProfileCommon, але він успадковуватиметься від вашого спеціального профілю профілю. Якщо ви не вказали спеціальний клас профілю, профіль ProfileCommon успадкує від System.Web.Profile.ProfileBase.
Якщо ви створюєте свій власний клас профілю, переконайтеся, що ви не вказали властивості профілю у файлі Web.config, який ви вже декларували у власному класі профілю. Якщо ви зробите ASP.Net, він видасть помилку компілятора при спробі генерування класу ProfileCommon.
Профіль можна використовувати і в проектах веб-додатків. Властивості можна визначити в Web.config під час проектування або програмно. В 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>
або Програмно, створити розділ профілю, інстанціюючи ProfileSection та створивши окремі властивості, використовуючи ProfilePropertySettings та ProfilePropertySettingsColletion , які знаходяться в просторі імен System.Web.Configuration. Для використання цих властивостей профілю використовуйте System.Web.Profile.ProfileBase Objects. Не можна отримати доступ до властивостей профілю за допомогою профілю. синтаксис, як згадувалося вище, але це легко зробити, встановивши ідентифікацію ProfileBase і використовуючи SetPropertyValue (" PropertyName ") та GetPropertyValue {" PropertyName ") таким чином:
ProfileBase curProfile = ProfileBase.Create("MyName");
або для доступу до профілю поточного користувача:
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
об’єкт і посилаючись на нього GetPropertyValue("PropName")
?
Коли ви створюєте новий проект веб-сайту у Visual Studio, об’єкт, який повертається з профілю, буде (автоматично) генерований для вас. Коли ви створюєте проект веб-додатків або проект MVC, вам доведеться прокрутити свій власний.
Це, мабуть, звучить складніше, ніж це є. Вам потрібно зробити наступне:
Якщо ви використовуєте проект веб-додатків, ви не можете отримати доступ до об’єкта профілю під час проектування поза межами коробки. Ось утиліта, яка нібито робить це за вас: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Особисто ця утиліта спричинила помилку в моєму проекті, тому я закінчив прокручувати власний клас профілю, щоб успадкувати від ProfileBase. Це зовсім не важко було зробити.
Покрокова інструкція MSDN для створення користувацького класу (також метод Джоеля):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
Я також переживав той самий випуск. Але замість створення класу, який успадковується від ProfileBase, я використовував HttpContext.
Вкажіть властивості у файлі web.config наступним чином: -
Тепер напишіть наступний код: -
Складіть і запустіть код. Ви отримаєте наступний вихід: -
Інструмент веб-профілів для мене відмінно працював. Клас, який він створив, містить у собі набагато більше, ніж описано у публікації Джоела. Незалежно від того, потрібна вона чи корисна, чи не знаю я.
У будь-якому випадку для тих, хто шукає простий спосіб генерувати клас, але не бажаючи мати зовнішню залежність від інструменту побудови, ви завжди можете
АБО (не перевірено, але може просто працювати)
якщо цей другий підхід спрацює, може хтось повідомив мене для подальшого ознайомлення
Просто хочу додати відповідь Джоела Спольського
Я реалізував його рішення, працюючи блискуче btw - Cudos!
Для тих, хто хоче отримати профіль користувача, який не ввійшов у користувач, який я використовував:
web.config:
<connectionStrings>
<clear />
<add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" />
</connectionStrings>
і
<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/>
</providers>
І тоді мій спеціальний клас:
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(); }
}
}
}
Працює як шарм ...
Чудовий пост,
Лише примітка на web.config, якщо ви не вказуєте атрибут спадкування в елементі профілю, вам потрібно буде вказати кожну властивість профілю індивідального профілю всередині елемента профілю на web.config, як показано нижче
<properties>
<clear/>
<add name="property-name-1" />
<add name="property-name-2" />
..........
</properties>