$\begingroup$

I come from a MVVM in WPF background moving towards ASP.NET MVC. I have a model that is composed of another model called Message, like so:

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

    [Required]
    [Display(Name = "Register Date")]
    public DateTime RegisterDate { get; set; }

    [Required]
    [StringLength(100)]
    public string Username { get; set; } = string.Empty;
    
    [Required]
    public Role Role { get; set; }

    public List<Message> Messages { get; set; } = new();
}

I am looking to display the latest message on the index page. If this was WPF, I would create a view model to expose this as a new attribute to interface with the view. In MVC, this could be incorporated into the controller as such:

public async Task<IActionResult> Index()
{
    var users = await _context.Users
        .Include(u => u.Messages)
        .ToListAsync();

    var vm = users.Select(u => new UserListViewModel
    {
        Id = u.Id,
        RegisterDate = u.RegisterDate,
        Username = u.Username,
        Role = u.Role,
        LatestMessage = u.Messages?.OrderByDescending(m => m.Timestamp)
            .FirstOrDefault()?.Content ?? string.Empty
    });

    return View(vm);
}

Alternatively, this could be incorporated on the model itself with the [NotMapped] annotation. However, this seems incorrect coming from WPF MVVM, since the LatestMessage field is only used for the view, and violates the separation of concerns that I am used to:

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

    [Required]
    [Display(Name = "Register Date")]
    public DateTime RegisterDate { get; set; }

    [Required]
    [StringLength(100)]
    public string Username { get; set; } = string.Empty;
    
    [Required]
    public Role Role { get; set; }

    public List<Message> Messages { get; set; } = new();

    [NotMapped]
    public string LatestMessage => 
        Messages?.OrderByDescending(m => m.Timestamp)
        .FirstOrDefault()?.Content ?? string.Empty;
}

I wondered which is better practice in ASP.NET MVC, or if there is altogether a better way of doing this?

$\endgroup$