Search code examples
asp.net-coreentity-framework-coreasp.net-identity

Recommended approach to show a custom user property in a view?


I'm trying to build a simple helpdesk application. In this app, when a ticket is created and displayed, I want to show the first name of the creating user. I am trying to solve how to do this in the best possible way.

I've extended the ApplicationUser class and added FirstName and LastName columns. I also created two foreign keys in my Tickets table, one for the user who created the ticket and one for the agent gets assigned to that ticket. So when the ticket is displayed, I need to show both creators and agents first name + last name's, instead of their UserId's.

This is my ApplicationUser class

public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public ICollection<Ticket> Users { get; set; }
        public ICollection<Ticket> Agents { get; set; }
    }

This is my model:

public class Ticket
    {
        public int Id { get; set; }

        public string Subject { get; set; }
        public string Body { get; set; }
        public int Status { get; set; }

        public string UserId { get; set; }
        public string AgentId { get; set; }

        public DateTime Created { get; set; }
        public DateTime LastUpdated { get; set; }
        public DateTime? Completed { get; set; }
        public bool Muted { get; set; }

        [ForeignKey("UserId")]
        public virtual ApplicationUser TicketUser { get; set; }

        [ForeignKey("AgentId")]
        public virtual ApplicationUser TicketAgent { get; set; }
    }

This is my DbContext:

        public DbSet Tickets { get; set; }

       protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity()
                        .HasOne(m => m.TicketUser)
                        .WithMany(t => t.Users)
                        .HasForeignKey(m => m.UserId)
                        .OnDelete(DeleteBehavior.Restrict);


            modelBuilder.Entity()
                        .HasOne(m => m.TicketAgent)
                        .WithMany(t => t.Agents)
                        .HasForeignKey(m => m.AgentId)
                        .OnDelete(DeleteBehavior.Restrict);
       }

This is the controller action to display a specific ticket:

    [HttpGet]
    public ViewResult Tickets(int id)
    {
        TicketDetailsViewModel ticketDetailsViewModel = new TicketDetailsViewModel()
        {
            Ticket = _ticketRepo.GetTicket(id)
        };


        return View(ticketDetailsViewModel);
    }

This is my viewmodel:

public class TicketDetailsViewModel
{
    public Ticket Ticket { get; set; }
}

Now, I can display the full name in my view if I do this:

@inject UserManager userManager;

@{
    var ticketUser = (await userManager.FindByIdAsync(Model.Ticket.UserId)).FirstName + " " + (await userManager.FindByIdAsync(Model.Ticket.UserId)).LastName;
}

But I am not sure if this is a good way to do it. I'd like to learn what is the best way to achive this.

Thank you very much.


Solution

  • You can define a _fullname in your ApplicationUser , and then if firstname and lastname both exist, you can directly call Fullname, like:

    public class ApplicationUser : IdentityUser
    {
        private string _fullName;  //new property
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        [NotMapped]
        public string FullName
        {
            get
            {
                return _fullName = this.FirstName + "." + this.LastName;
            }
            set
            {
                _fullName = value;
            }
        }
    
        public ICollection<Ticket> Users { get; set; }
        public ICollection<Ticket> Agents { get; set; }
    }
    

    In view, just call FullName:

    @{
    var ticketUser = (await userManager.FindByIdAsync(Model.Ticket.UserId)).FullName;
    }
    

    enter image description here