Profile Object + View Model + Updating User Profile MVC C#

5.9k views Asked by At

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

There are 1 answers

0
Reynolds On

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:

<profile defaultProvider="TableProfileProvider" enabled="true" inherits="YourNamespace.YourClass, YourNamespace">

Great MSDN article here, here, and here.

I hope these get you on your way!