Nitesh Kumar
Nitesh Kumar

Reputation: 1774

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?

Upvotes: 6

Views: 7979

Answers (4)

user1023602
user1023602

Reputation:

The URL is already different when searching for doctors and patients, so there is no benefit in having a single action.

Just write two Actions "GetDoctors" and "GetPatients" which return the types you want.

[ResponseType(typeof(List<InboxPatientModel>))]
[Route("~/api/Messages/searchpatients")]
public IHttpActionResult GetPatients(string searchTerm = "")
{
}

[ResponseType(typeof(List<InboxDoctorModel>))]
[Route("~/api/Messages/searchdoctors")]
public IHttpActionResult GetDoctors(string searchTerm = "")
{
}

Upvotes: 3

CodeCaster
CodeCaster

Reputation: 151720

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))].

Upvotes: 3

Francisco Goldenstein
Francisco Goldenstein

Reputation: 13787

Each resource (patient and doctor) should have its own controller action. I would do this:

1) Create two different controller actions: one for InboxPatientModel and another one for InboxDoctorModel.

2) At the client-side you determine, based on "messageFor", which controller action you need to call.

3) Eeach controller action would have a different ResponseType.

Upvotes: 2

Emre Kabaoglu
Emre Kabaoglu

Reputation: 13146

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....
    }
}

Upvotes: 6

Related Questions