9

In the ASP.Net MVC 5, the ApplicationUser can be extended to have custom property. I have extended it such that it now has a new property called DisplayName:

// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser {
    public string ConfirmationToken { get; set; }
    public string DisplayName { get; set; } //here it is!

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

I also have updated the database table using Update-Database command in the Package-Manager Console in Visual Studio to ensure the consistency between the ApplicationUser class and the AspNetUsers table. I have confirmed that the new column called DisplayName is now exist in the AspNetUsers table.

enter image description here

Now, I want to use that DisplayName instead of the default UserName for the text in the original _LoginPartial.cshtml View. But as you can see:

<ul class="nav navbar-nav navbar-right">
  <li>
    @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
  </li>
  <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>

The original _LoginPartialView.cshtml is using User.Identity.GetUserName() to get the UserName of the ApplicationUser. The User.Identity has GetUserId and also Name, AuthenticationType, etc... But how do I get my DisplayName for display?

tmg
  • 19,895
  • 5
  • 72
  • 76
Ian
  • 30,182
  • 19
  • 69
  • 107

1 Answers1

14

Add the claim in ClaimsIdentity:

public class ApplicationUser : IdentityUser
{
    ...

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("DisplayName", DisplayName));
        return userIdentity;
    }
}

Created an extention method to read DisplayName from ClaimsIdentity:

public static class IdentityExtensions
{
    public static string GetDisplayName(this IIdentity identity)
    {
        if (identity == null)
        {
            throw new ArgumentNullException("identity");
        }
        var ci = identity as ClaimsIdentity;
        if (ci != null)
        {
            return ci.FindFirstValue("DisplayName");
        }
        return null;           
    }
}

In your view use it like:

User.Identity.GetDisplayName()
tmg
  • 19,895
  • 5
  • 72
  • 76
  • This seems promising... where do you normally place your `IdentiyExtensions` method? In the `IdentityModels.cs`? Or would you create a new file with certain name convention for it? – Ian Aug 09 '16 at 09:35
  • I would create a new file with name "IdentityExtensions.cs", probably inside a folder named "Helpers" – tmg Aug 09 '16 at 09:37
  • Thanks for your answer! It works! I make a little modification though... instead of returning `return claim.FindFirst("DisplayName")`, I return `return claim.FindFirst("DisplayName").ToString().Substring(("DisplayName: ").Length);` -- this is because `claim.FindFirst("DisplayName")` is of type `Claim` but the `return` needs to be a `string`. Also, if I do not put the `Substring`, it will display `DisplayName: myname` instead of just `myname`. – Ian Aug 09 '16 at 09:50
  • @Ian you are correct about returning string. I updated the the extension method. – tmg Aug 09 '16 at 09:56
  • I do not find the `FindFirstValue` method (there isn't one). Do I miss any reference? Thanks for the update - I accepted your answer anyway, since it already sufficiently points to the right answer. ;) – Ian Aug 09 '16 at 09:59
  • its in the Microsoft.AspNet.Identity namespace – tmg Aug 09 '16 at 10:00
  • I get it... forgot about `Ctrl + .` yep, thanks again! – Ian Aug 09 '16 at 10:01
  • Can I use this extension for int values? – akd Nov 23 '16 at 13:11