I\'m working on an ASP.Net vNext / MVC6 project. I\'m getting to grips with ASP.Net Identity.
The ApplicationUser class is apparently where I\'m suppose
OK, here's how I eventually did it. I used a new feature in MVC6 called View Components. These work a bit like partial views, but they have a "mini controller" associated with them. The View Component is a lightweight controller that doesn't participate in model binding, but it can have something passed to it in constructor parameters, possibly using dependency injection and then it can construct a View Model and pass that to a partial view. So, for example, you can inject a UserManager instance into the View Component, use that to retrieve the ApplicationUser object for the current user and pass that to the partial view.
Here's what it looks like in code. First, the View Component, which lives in /ViewComponents directory:
public class UserProfileViewComponent : ViewComponent
{
readonly UserManager userManager;
public UserProfileViewComponent(UserManager userManager)
{
Contract.Requires(userManager != null);
this.userManager = userManager;
}
public IViewComponentResult Invoke([CanBeNull] ClaimsPrincipal user)
{
return InvokeAsync(user).WaitForResult();
}
public async Task InvokeAsync([CanBeNull] ClaimsPrincipal user)
{
if (user == null || !user.IsSignedIn())
return View(anonymousUser);
var userId = user.GetUserId();
if (string.IsNullOrWhiteSpace(userId))
return View(anonymousUser);
try
{
var appUser = await userManager.FindByIdAsync(userId);
return View(appUser ?? anonymousUser);
}
catch (Exception) {
return View(anonymousUser);
}
}
static readonly ApplicationUser anonymousUser = new ApplicationUser
{
Email = string.Empty,
Id = "anonymous",
PhoneNumber = "n/a"
};
}
Note that the userManager constructor parameter is injected by the MVC framework; this is configured by default in Startup.cs in a new project so there's no configuration to be done.
The view component is invoked, unsurprisingly, by calling the Invoke method or the asynchronous version of it. The method retrieves an ApplicationUser if possible, otherwise it uses an anonymous user with some safe defaultspreconfigured. It uses this user to its partiel view s the view model. The view lives in /Views/Shared/Components/UserProfile/Default.cshtml and starts like this:
@model ApplicationUser
@Html.GravatarImage(Model.Email, size:80)
@Model.UserName
@Model.PhoneNumber
And finally, I invoke this from within my _Navigation.cshtml partial view like so:
@await Component.InvokeAsync("UserProfile", User)
This meets all of my original requirements, because:
Result! I hope someone will find this useful...