Home > Back-end >  Return Full Name from Another Table in Login Partial View
Return Full Name from Another Table in Login Partial View

Time:11-23

I am using asp.net core identity, but have deliberately separated the user specific information into another table which is linked via the application user class.

How would I access this information from the login partial view?

Other answers only define so far as to pull the information from the application user class. ie:

var personID = UserManager.GetUserAsync(User).Result.PersonID;

Where as I need something like:

var fullName = UserManager.GetUserAsync(User).Result.Person.FullName;

I'm guessing the code behind doesn't load the child table, as I get the the following error on the Person object:

'Object reference not set to an instance of an object.'

The rest of my code is below for reference.

Application User:

  public class ApplicationUser : IdentityUser
    {
        [ForeignKey("Person")]
        public int PersonID { get; set; }

        public virtual Person Person { get; set; }    
    }

Person Class

public class Person
{
    public int PersonID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    [NotMapped]
    [Display(Name = "Full Name")]
    public string FullName
    {
        get { return LastName   ", "   FirstName; }
    }

    public string Address { get; set; }

    public ApplicationUser ApplicationUser { get; set; }

}

Login Partial:

@using Microsoft.AspNetCore.Identity
@using Models;
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

<ul >
@if (SignInManager.IsSignedIn(User))
{
    <li >
        <a   asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity?.Name!</a>
        @{
                var personResult = UserManager.GetUserAsync(User).Result;
                var fullName = personResult.Person.FullName;                
            }  
          
    </li>
    <li >
        <form  asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post" >
            <button  type="submit" >Logout</button>
        </form>
    </li>
}
else
{
    <li >
        <a  asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li >
        <a  asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

CodePudding user response:

_userManager.GetUserAsync(User) is based on EF Core, it won't load related data by defalut,you could try with lazyloading as the enter image description here

Models:

public class ApplicationUser : IdentityUser
{
    
    //you have to set the property virtual here
    public virtual Person Person { get; set; }
}

public class Person
{
    public int PersonID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    [NotMapped]
    [Display(Name = "Full Name")]
    public string FullName
    {
        get { return LastName   ", "   FirstName; }
    }

    public string Address { get; set; }
    //you have to set the property virtual here
    public virtual ApplicationUser ApplicationUser { get; set; }

    public string ApplicationUserId { get; set; }

}

modified the codes which regist the dbcontext:

builder.Services.AddDbContext<IdentityLazyloadingContext>(options =>
{
    options.UseSqlServer(connectionString);
    options.UseLazyLoadingProxies();
});

The result:

enter image description here

CodePudding user response:

Answer from Ruikai Feng marked as answer as it set me on the right track. However I ended up using lazy loading without the proxies framework as follows:

LazyLoading

   public class ApplicationUser : IdentityUser
    {
        private Person _Person;

        public ApplicationUser()
        {
        }

        private ApplicationUser(Action<object, string> lazyLoader)
        {
            LazyLoader = lazyLoader;
        }

        private Action<object, string> LazyLoader { get; set; }

        [ForeignKey("Person")]
        public int PersonID { get; set; }

        public Person Person
        {
            get => LazyLoader.Load(this, ref _Person);
            set => _Person = value;
        }
    }

Extension:

  public static class PocoLoadingExtensions
    {
        // Load function for Lazy Loading, used in Application User.

        public static TRelated Load<TRelated>(
            this Action<object, string> loader,
            object entity,
            ref TRelated navigationField,
            [CallerMemberName] string navigationName = null)
            where TRelated : class
        {
            loader?.Invoke(entity, navigationName);

            return navigationField;
        }
    }
  • Related