2

Considerations

I created a new MVC4 internet application. Out of the box, it comes with this class in the account models:

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

It looks like a good place to add all my other user information and to link my tables to. The fact that it's called a "Profile" seems a bit odd to me, as this appears to be the "base" user class.

I see a table in the database called webpages_Membership, but I don't know where the model for that is. When using OpenID to create an account, it doesn't look like a record even gets inserted in there. I believe that's just for local accounts, thus "UserProfile" seems to be the only thing a user is guaranteed to have.

Anyway, the base Controller class appears to have a Profile property defined as a ProfileBase but when I inspect using the debugger, it's a System.Web.Profile.DefaultProfile, and it doesn't seem to be "filled in". i.e., IsAnonymous is true, and UserName is null, even when I'm logged in.

I'm guessing this is intentional? Am I expected to override that by defining my own base controller?

I see this question and this article which talk about extending ProfileBase, but that approach seems a bit messy to me.

Question

With all the aforementioned considerations, it seems best to me to just add all my extra properties to the UserProfile class that's already been created for me, then add a new BaseController class that extends Controller, and override/new the Profile property to return a UserProfile instead. (1) Is this a good approach?

It took me awhile, but I eventually figured out how to get the UserProfile object for the currently logged in user:

udb.UserProfiles.Single(p => p.UserName == User.Identity.Name);

(2) Is that the best way to get it? The UserProfile has a UserId property, but I can't figure out how to retrieve it. (3) How can I get the UserId for the currently logged in user?

I was thinking I could have the property lazy-load the profile so it only hits the database the first time you access that property. I read some other articles that talk about json-serializing the entire user class so it doesn't have to hit the DB every page load, but that sounds even messier, and you risk the data getting out of sync.

Implementation

Just tried this:

public class BaseController : Controller
{
    private UsersContext _udb = new UsersContext();
    private UserProfile _profile = null;

    public new UserProfile Profile
    {
        get
        {
            if(_profile == null && User.Identity.IsAuthenticated)
            {
                _profile = _udb.UserProfiles.Single(p => p.UserName == User.Identity.Name);
            }
            return _profile;
        }
    }
}

Seems to work flawlessly.

4

0 回答 0