Problem: I have created a custom profile object as described by Joel here. I then used Jeremy's method (here) to extend the custom profile to allow me to use generate a user and set those values. I then created a ViewModel to display Memeberhip information and Profile Information so that the user can update their membership info (email) and Profile Information. **The view displays all of the fields I enter in the updated information in the view and click save, where I get the following error
System.Configuration.SettingsPropertyNotFoundException: The settings property 'FirstName' was not found. **
Here's my custom Profile Object (Model):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Profile;
using System.Web.Security;
namespace NDAC.Models
{
public class ProfileInformation : ProfileBase
{
static public ProfileInformation CurrentUser
{
get
{
if (Membership.GetUser() != null)
{
return (ProfileInformation)(ProfileBase.Create(Membership.GetUser().UserName));
}
else
{
return null;
}
}
}
public virtual string FirstName {
get
{
return ((string)(base["FirstName"]));
}
set
{
base["FirstName"] = value; Save();
}
}
public virtual string LastName {
get
{
return ((string)(base["LastName"]));
}
set
{
base["LastName"] = value; Save();
}
}
public string Street
{
get
{
return ((string)(base["Street"]));
}
set
{
base["Street"] = value; Save();
}
}
public string Street2
{
get
{
return ((string)(base["Street2"]));
}
set
{
base["Street2"] = value; Save();
}
}
public string City
{
get
{
return ((string)(base["City"]));
}
set
{
base["City"] = value; Save();
}
}
public string State
{
get
{
return ((string)(base["State"]));
}
set
{
base["State"] = value; Save();
}
}
public string ZipCode
{
get
{
return ((string)(base["ZipCode"]));
}
set
{
base["ZipCode"] = value; Save();
}
}
public string PhoneNumber
{
get
{
return ((string)(base["PhoneNumber"]));
}
set
{
base["PhoneNumber"] = value; Save();
}
}
public string SemesterID
{
get
{
return ((string)(base["SemesterID"]));
}
set
{
base["SemesterID"] = value; Save();
}
}
static public ProfileInformation GetProfile(string username)
{
return Create(username) as ProfileInformation;
}
internal static ProfileInformation NewUser
{
get { return System.Web.HttpContext.Current.Profile as ProfileInformation; }
}
}
}
Here is the UserProfile Get Method:
[Authorize]
public ActionResult UserProfile()
{
string id = User.Identity.Name.ToString();
MembershipUser user = Membership.GetUser(id);
var model = new UserViewModel();
UserInformation userInf = new UserInformation();
userInf.Username = user.UserName;
userInf.Email = user.Email;
ProfileInformation currentProfile = ProfileInformation.GetProfile(user.UserName);
model.Profile = currentProfile;
model.UserInf = userInf;
return View(model);
}
As you can see I'm using a View Model to display the view. The View Model is this:
public class UserViewModel
{
public UserInformation UserInf{ get; set; }
public ProfileInformation Profile { get; set; }
}
And finally the HttpPost Method for the Update UserProfile is:
[Authorize]
[HttpPost]
public ActionResult UserProfile(UserViewModel model)
{
ProfileInformation currentProfile = ProfileInformation.GetProfile(User.Identity.Name.ToString());
ProfileInformation.CurrentUser.FirstName = model.Profile.FirstName;
currentProfile.LastName = model.Profile.LastName;
currentProfile.Street = model.Profile.Street;
currentProfile.Street2 = model.Profile.Street2;
currentProfile.City = model.Profile.City;
currentProfile.State= model.Profile.State;
currentProfile.ZipCode = model.Profile.ZipCode;
currentProfile.PhoneNumber = model.Profile.PhoneNumber;
currentProfile.Save();
MembershipUser user = Membership.GetUser(User.Identity.Name.ToString());
user.Email = model.UserInf.Email;
Membership.UpdateUser(user);
TempData["SuccessMessage"] = "Your Profile information has been saved";
ViewBag.Title = "My Profile";
return RedirectToAction("ProfileUpdated");
}
The problem is I can't figure out where the error is coming from. The form renders I input valid information and then I'm told "The settings property 'FirstName' was not found." It's like the UserViewModel is attempting to update the ProfileInformation.cs (custom profile object) but it's saying it can't find the object... I'm thinking it's because it doesn't have a profile to update... but I can't get to the error before it posts... so frustrating! Any help would be greatly appreciated!!! Thanks for taking the time to check this out.
I'll also leave you with my Register method which uses the custom Profile object successfully and even updates the name property to "ScoobyDoo" for testing purposes :)
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email, model.SecretQuestion, model.SecretAnswer);
if (createStatus == MembershipCreateStatus.Success)
{
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
Roles.AddUserToRole(model.UserName, "Student");
ProfileInformation.NewUser.Initialize(model.UserName, true);
ProfileInformation.NewUser.Save();
string currentSemesterID = CurrentSemester;
ProfileInformation profile = ProfileInformation.GetProfile(model.UserName);
profile.SemesterID = currentSemesterID;
profile.FirstName = "ScoobyDoo";
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
ViewBag.PasswordLength = MembershipService.MinPasswordLength;
return View(model);
}
You may need to provide the your own profile implementation... If you have done that, have you added your custom provider type to your "web.config"?
Example:
Great MSDN article here, here, and here.
I hope these get you on your way!