Search code examples
c#dto

How to I return a List of DTOs from my API controller


I have a class :

public class Participant
{
    [Key]
    public int ParticipantId { get; set; }

    [Column(TypeName ="nvarchar(50)")]
    public string Email { get; set; }

    [Column(TypeName = "nvarchar(50)")]
    public string Name { get; set; }

    public int Score { get; set; }

    public int Timetaken { get; set; }
}

My endpoint:

 public IActionResult GetAll()
    {
        var parts = _context.Participants.ToList();

        if(!parts.Any())
            return NotFound();

        var participant = new ParticipantDto(parts);

        return Ok(participant);
    }

My Participant Dto:

 public class ParticipantDto
{
    private readonly Participant _participants;
    public ParticipantDto(Participant participants)
    {
        _participants = participants;
    }
}

I am trying the approach of passing the Participant object in the constructor and then assigning the Participant properties to DTO. I am aware how to do it for one Participant :

   public string EmailAddress = _participants.Email;
   etc

However, what If I want to return a List, how do I need to update my Dto to handle that?


Solution

  • For this statement,

    var participant = new ParticipantDto(parts);
    

    it is incorrect as you are passing the List<Participant> instance to the ParticipantDto constructor which the constructor is expected for the parameter value with the Participant type. You will get the compiler error for the unmatching type.

    Hence, you need to iterate the list to transform each Participant element to the ParticipantDto type. You can use .Select() from System.Linq to do the iteration and transformation.

    public IActionResult GetAll()
    {
        var parts = _context.Participants.ToList();
    
        if(!parts.Any())
            return NotFound();
    
        List<ParticipantDto> participants = parts
            .Select(x => new ParticipantDto(participant))
            .Tolist();
    
        return Ok(participants);
    }
    

    While in ParticipantDto, you need to perform the value mapping between the properties.

    public class ParticipantDto
    {
        public ParticipantDto(Participant participant)
        {
            Email = participant.Email;
            Name = participant.Name;
    
            // Following assigning value from the properties of Participant to properties of ParticipantDto 
        }
    
        public string Email { get; set; }
    
        public string Name { get; set; }
    
        // Following properties
    }
    

    Bonus:

    You may look for AutoMapper which is a popular library for mapping between classes. (Wouldn't cover too much as the answer aims to focus and fix your current problem)