Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return different types of model from a WebAPI controller action?

I have a controller like this

    [ResponseType(typeof(List<InboxPatientModel>))]
    [Route("~/api/Messages/search")]
    public IHttpActionResult GetSearch(string serchTerm = "", string messageFor = "p")
    {
        try
        {
            if(messageFor == "p")
            {
                var inboxMessages = MessageToPatientList.Get(serchTerm);
                return Ok(inboxMessages);
            }
            else
            {
                var outboxMessages = MessageToDoctorList.Get(serchTerm);
                return Ok(outboxMessages);
            }
        }
        catch (Exception ex)
        {
             //some code for exception handling....
        }
    }

Here MessageToPatientList.Get and MessageToDoctorList.Get return list of different types say InboxPatientModel and InboxDoctorModel.

Is it possible to decorate the action with [ResponseType(...)] so that it can be dynamic and different types of list can be returned?

like image 790
Nitesh Kumar Avatar asked Jan 11 '18 12:01

Nitesh Kumar


People also ask

What types can Web API action method return?

A Web API controller action can return any of the following: void. HttpResponseMessage. IHttpActionResult.

Can you return an action from Web API?

An action method in Web API 2 can return an implementation of IHttpActionResult class which is more or less similar to ActionResult class in ASP.NET MVC.


2 Answers

You could merge the different types of lists;

public class PatientModel
{
    public List<InboxPatientModel> Patients { get; set; }

    public List<InboxDoctorModel> Doctors { get; set; }
}

[ResponseType(typeof(PatientModel))]
[Route("~/api/Messages/search")]
public IHttpActionResult GetSearch(string serchTerm = "", string messageFor = "p")
{
    try
    {
        var patientModel = new PatientModel();
        if (messageFor == "p")
        {
            var inboxMessages = MessageToPatientList.Get(serchTerm);
            patientModel.Patients = inboxMessages;
        }
        else
        {
            var outboxMessages = MessageToDoctorList.Get(serchTerm);
            patientModel.Doctors = inboxMessages;
        }
        return Ok(patientModel);
    }
    catch (Exception ex)
    {
        //some code for exception handling....
    }
}
like image 108
lucky Avatar answered Nov 14 '22 21:11

lucky


Your code will run just fine. The [ResponseType] attribute is only used to give hints for the Web API documentation page and tools like Swagger.

While the attribute has AllowMultiple=true in its AttributeUsage attribute, I don't think those documentation tools support this.

And they shouldn't. Returning different types from an API depending on the size of the moon, the day of the week or the value of some parameters is a hell to implement, a hell to document and a hell to consume.

Instead consider reviewing the design. Why should the actual type of a message change depending on who is the recipient? What is different between the two types of messages?

On the contrary, find properties they share. Then extract a base class, say, Message, and decorate the method with an attribute [ResponseType(typeof(Message))].

like image 23
CodeCaster Avatar answered Nov 14 '22 21:11

CodeCaster