32

I have an MVC 3 intranet application that performs windows authentication against a particular domain. I would like to render the current user's name.

in the view,

@User.Identity.Name 

is set to DOMAIN\Username, what I want is their full Firstname Lastname

Charles Ma
  • 47,141
  • 22
  • 87
  • 101

5 Answers5

58

You can do something like this:

using (var context = new PrincipalContext(ContextType.Domain))
{
    var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);
    var firstName = principal.GivenName;
    var lastName = principal.Surname;
}

You'll need to add a reference to the System.DirectoryServices.AccountManagement assembly.

You can add a Razor helper like so:

@helper AccountName()
    {
        using (var context = new PrincipalContext(ContextType.Domain))
    {
        var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);
        @principal.GivenName @principal.Surname
    }
}

If you indend on doing this from the view, rather than the controller, you need to add an assembly reference to your web.config as well:

<add assembly="System.DirectoryServices.AccountManagement" />

Add that under configuration/system.web/assemblies.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • I just tried to implement the razor helper and is throwing an error (can't find the reference), but using System.DirectoryServices.AccountManagement works from C# files and the dll is included in the project references, any ideas? – Charles Ma Jan 18 '12 at 01:28
  • 5
    Figured it out, had to set the "copy local" property of the DLLs to true. :) – Charles Ma Jan 18 '12 at 01:35
  • 4
    For MVC4, web.config needs `` in `configuration/system.web/pages/namespaces`. – Lawtonfogle Aug 22 '14 at 18:18
  • Hey...this worked for me .. I was having a verison inside this, and had all issue. After removing the version all good. – Buminda Oct 12 '17 at 01:39
7

Another option, without requiring a helper... You could just declare context and principal before you need to utilize these values, and then utilize it like a standard output...

@{ // anywhere before needed in cshtml file or view
    var context = new PrincipalContext(ContextType.Domain);
    var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);
}

Then anywhere within the document, just call each variable as needed:

@principal.GivenName // first name
@principal.Surname // last name
Sean Haddy
  • 1,630
  • 1
  • 16
  • 25
  • 1
    This is essentially the same answer as the previous one, but not requiring a helper is a plus in my opinion, so I like your answer better. :) – DigiOz Multimedia Sep 25 '14 at 18:00
3

If you have many controllers then using @vcsjones approach might be painfull. Therefore I'd suggest creating extension method for TIdentity.

public static string GetFullName(this IIdentity id)
    {
        if (id == null) return null;

        using (var context = new PrincipalContext(ContextType.Domain))
        {
            var userPrincipal = UserPrincipal.FindByIdentity(context, id.Name);
            return userPrincipal != null ? $"{userPrincipal.GivenName} {userPrincipal.Surname}" : null;
        }
    }

And then you can use it in your view:

<p>Hello, @User.Identity.GetFullName()!</p>
Leon
  • 147
  • 2
  • 7
1

If you've upgraded to Identity 2 and are using claims, then this kind of info would be a claim. Try creating an extension method:

public static string GetFullName(this IIdentity id)
{
    var claimsIdentity = id as ClaimsIdentity;

    return claimsIdentity == null 
        ? id.Name 
        : string.Format("{0} {1}", 
            claimsIdentity.FindFirst(ClaimTypes.GivenName).Value, 
            claimsIdentity.FindFirst(ClaimTypes.Surname).Value);
}

Then you can use it in the view like this:

@Html.ActionLink("Hello " + User.Identity.GetFullName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
Sinaesthetic
  • 11,426
  • 28
  • 107
  • 176
  • Hi @Sinaesthetic. Could you pass me some link which explains ClaimsIdentity from the scartch up? – Sandeep Nov 13 '15 at 06:38
0

Add the below in your _ViewImports.cshtml page :

@using System.DirectoryServices.AccountManagement

Then, in your _Layouts.cshtml place the below :

@{ 
var context = new PrincipalContext(ContextType.Domain);
var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);}

Note: You can concatenate by creating additional variable ex:

var userName = @principal.Givenname + ", " + @principal.Surname;

You can not call the variable 'userName' directly, however, you can call 'userName' anywhere on the page by creating a hidden field.

Satish
  • 1