Varanasi Phaneendra
Varanasi Phaneendra

Reputation: 199

Array request in MediatR command handler

I have below request

[
  {
    
    "firstName": "first_name",
    "lastName": "last_name",
    "phoneNumber": "phone_niumber",
    "email": "emai_domaon",
    "fax": "fax_number",
    "phoneNumberExt": "ext1",
    "mobileNumber": "394858"
  },
  {
    "firstName": "first_nam2e",
    "lastName": "last_name2",
    "phoneNumber": "phone_2niumber",
    "email": "emai_domaon2",
    "fax": "fax_number2",
    "phoneNumberExt": "ext12",
    "mobileNumber": "3948528"
  }
]

Its a array request, how do I define the IRequestHandler, I created another class and used in handler class

 public class ContactCommandRequest : BaseContact
    {
        /// <summary>
        /// Gets or sets phone number extension.
        /// </summary>
        public string PhoneNumberExt { get; set; }

        /// <summary>
        /// Gets or sets mobile number.
        /// </summary>
        public string MobileNumber { get; set; }

    }

and using another class for IRequest

public class ContactCommand : IRequest<StudentRegisterResponse>
    {
        public ContactCommand(List<ContactCommandRequest> req)
        {
            this.Contacts = req;
        }

        public List<ContactCommandRequest> Contacts { get; private set; }
    }

Inside controller

public async Task<IActionResult> ContactDetails([FromBody] List<ContactCommand> request, CancellationToken cancellationToken = default)
        {
            return Ok(await this.mediator.Send(new ContactCommand(request), cancellationToken));
        }

Is there any better way in handling the array list request in MediatR

Upvotes: 0

Views: 4234

Answers (1)

Oliver
Oliver

Reputation: 45071

Just tried to give you a sketch about how to set it up. Here are some base classes holding the desired information:

public class Contact : BaseContact
{
    public string PhoneNumberExt { get; set; }
    public string MobileNumber { get; set; }
}

public class BaseContact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Fax { get; set; }
}

public class StudentRegisterResponse
{
    public bool Done { get; set; }
}

Depending on how much you can infere the design of the incoming data you could either use this, if the body contains a plain array:

public class ContactsCreateRequest : IRequest<StudentRegisterResponse>
{
    public IReadOnlyList<Contact> Contacts { get; set; }
}

public static async Task<object> CreateContacts([FromBody] IReadOnlyList<Contact> contacts, CancellationToken cancellationToken)
{
    var request = new ContactsCreateRequest { Contacts = contacts };
    var response = await mediator.Send(request, cancellationToken);

    return Ok(response);
}

Or maybe this one:

public class ContactsCreateRequest : IRequest<StudentRegisterResponse>
{
    [FromBody]
    public IReadOnlyList<Contact> Contacts { get; set; }
}

public static async Task<object> CreateContacts(ContactsCreateRequest request, CancellationToken cancellationToken)
{
    var response = await mediator.Send(request, cancellationToken);

    return Ok(response);
}

Take care about the usage of the FromBodyAttribute and that it only appears once. Either on the method parameter OR on a property parameter. The FromQueryAttribute can appear multiple times on both levels.

The handler itself should then be something like this:

public class ContactsCreateHandler : IRequestHandler<ContactsCreateRequest, StudentRegisterResponse>
{
    public async Task<StudentRegisterResponse> Handle(ContactsCreateRequest request, CancellationToken cancellationToken)
    {
        foreach (var contact in request.Contacts)
        {
            Console.WriteLine($"{contact.FirstName} {contact.LastName}");
        }

        await Task.Delay(0);

        return new StudentRegisterResponse { Done = true };
    }
}

Upvotes: 3

Related Questions