Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I manage profiles using SimpleMembership?

I have an ASP.NET MVC 4 site based off the internet template. I am using the SimpleMembership which i set up with that template.

I can modify the Users table which has been creted for me but I am unsure as to the "correct" way to modify the extra fields I have added. I want Fullname, Email etc and have added them to the user table but there appears no way to update through the SimpleMembership WebSecurity.* static methods.

Are you supposed to just update those properties yourself using EF outside of the SimpleMembership API?

like image 244
PlanetWilson Avatar asked Sep 10 '12 12:09

PlanetWilson


3 Answers

1 - You need to enable migrations, prefereably with EntityFramework 5

2 - Move your

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

to your Seed method in your YourMvcApp/Migrations/Configuration.cs class

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }

Now EF5 will be in charge of creating your UserProfile table, after doing so you will call the WebSecurity.InitializeDatabaseConnection to only register SimpleMembershipProvider with the already created UserProfile table, also tellling SimpleMembershipProvider which column is the UserId and UserName. I am also showing an example of how you can add Users, Roles and associating the two in your Seed method with custom UserProfile properties/fields e.g. a user's Mobile (number) and IsSmsVerified.

3 - Now when you run update-database from Package Manager Console, EF5 will provision your table with all your custom properties

For additional references please refer to this article with sourcecode: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

like image 113
LeLong37 Avatar answered Oct 18 '22 20:10

LeLong37


They made it easy to modify the profile with SimpleMembership. SimpleMembership is using the code first EF model and the user profile is defined in the file AccountModels.cs that is generated as part of the Internet template for MVC 4. Just modify the class UserProfile and add the new fields in the class definition. For example, adding a field for email would look something like this:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
}

Here is an example on how you would access the email field:

var context = new UsersContext();
var username = User.Identity.Name;
var user = context.UserProfiles.SingleOrDefault(u => u.UserName == username);
var email = user.Email;

Here is what the database looks like after adding the email field.

enter image description here

There is a good blog that describes some of the changes in SimpleMembership here. You can also find more detailed information on customizing and seeding SimpleMembership here.

like image 26
Kevin Junghans Avatar answered Oct 18 '22 19:10

Kevin Junghans


if you look right around line 273 of the accountcontroller you'll find this line

db.UserProfiles.Add(new UserProfile { UserName = model.UserName });

Looks like even OOTB they (MS) are doing just as you suggested and using EF to update.

I too, am looking for the "correct" way of updating and accessing these properties.

Edit:

Here's my solution (I'm happy if someone says there's an OOTB way to do this).

wrap UserProfile (the .net Entity from SimpleMembership) in a session class.

public static class sessionHelpers {
     public static UserProfile userProfile
        {
            get
            {
                if (HttpContext.Current.Session["userProfile"] != null)
                {
                    return HttpContext.Current.Session["userProfile"] as UserProfile; 
                }
                else
                {
                    using (UsersContext db = new UsersContext())
                    {
                        HttpContext.Current.Session["userInfo"] =
                        db.UserProfiles.Where(x => x.UserName == 
                            HttpContext.Current.User.Identity.Name).FirstOrDefault();

                   return db.UserProfiles.Where(x => x.UserName == 
                       HttpContext.Current.User.Identity.Name).FirstOrDefault();
                    }
                }
            }
            set { HttpContext.Current.Session["userProfile"] = value; }
        }
}

From this you can access the profile table by doing

string foo = sessionHelpers.userProfile.FIELDNAME;

where sessionHelpers is my wrapper class. The if block just ensures that if it hasn't been set in the current session that accessing it will attempt to get it.

like image 4
Eonasdan Avatar answered Oct 18 '22 20:10

Eonasdan