Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a list of objects as an IHttpActionResult?

I'm new to ASP.NET webapi and I can't find a way to return a list of objects queried by id.

This is my controller method for the GET request. I want to return all the questions which have a specified questionnaireId passed via url.

I tried this:

// GET: api/Questions/5
[ResponseType(typeof(List<Question>))]
public Task<IHttpActionResult> GetQuestion(int questionnaireId)
{
    var questions = from q in db.Questions
    where q.QuestionnaireId == questionnaireId
    select new Question()
    {
            Id = q.Id,
            ImageLink = q.ImageLink,
            QuestionnaireId = q.QuestionnaireId,
            Text = q.Text
    };
    return questions;
}

This is my Question class:

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

        [ForeignKey("Questionnaire")]
        public int QuestionnaireId { get; set; }

        public string Text { get; set; }
        public string ImageLink { get; set; }

        public virtual Questionnaire Questionnaire { get; set; }
    }

But on return questions it shows the compiler error:

Cannot implicitly convert type System.Linq.IQueryable<finah_backend.Models.Question> to System.Web.Http.IHttpActionResult. An explicit conversion exists (are you missing a cast?)

I want to get a list of questions returned in JSON queried on questionnaireId, which is passed via a url i.e. api/questions/2 ==> gives me back all the questions with questionnaireId = 2.

like image 793
Rick Avatar asked Mar 20 '15 09:03

Rick


People also ask

What does IHttpActionResult return?

IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance. If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.

What is HttpResponseMessage?

A HttpResponseMessage allows us to work with the HTTP protocol (for example, with the headers property) and unifies our return type. In simple words an HttpResponseMessage is a way of returning a message/data from your action. The following is a quick glimpse of that: // GetEmployee action.

How many Types of return type in Web API?

Note that there are two possible return types in this action. If the employee with the specified id is not found, it returns a 404 Not Found response. On the other hand, once it finds the employee with the specified id, it returns a 200 Ok status code with the employee object.


2 Answers

You're using the [ResponseType] attribute, but that's only for generating documentation, see MSDN: ResponseTypeAttribute Class:

Use this to specify the entity type returned by an action when the declared return type is HttpResponseMessage or IHttpActionResult. The ResponseType will be read by ApiExplorer when generating ApiDescription.

You can either change your return type (and remove the attribute, as it isn't required anymore as the return type documentation will be generated from the actual signature):

public IEnumerable<Question> GetQuestion(int questionnaireId)

Or, if you want it to be async:

public async Task<IEnumerable<Question>> GetQuestion(int questionnaireId)

Or wrap the result in an IHttpActionResult, which the method Request.CreateResponse<T>() does:

 return Request.CreateResponse<IEnumerable<Question>>(HttpStatusCode.OK, questions);

The latter is done for you if you call the ApiController.Ok() method:

return Ok(questions);
like image 172
CodeCaster Avatar answered Sep 18 '22 14:09

CodeCaster


Just simply return it like this, you need to use one of the nice methods that ApiController now supplies.

This will return a status code of 200 along with your questions collection.

[ResponseType(typeof(List<Question>))]
public async Task<IHttpActionResult> GetQuestion(int questionnaireId)
{
    var questions = from q in db.Questions
    where q.QuestionnaireId == questionnaireId
    select new Question()
    {
            Id = q.Id,
            ImageLink = q.ImageLink,
            QuestionnaireId = q.QuestionnaireId,
            Text = q.Text
    };
    return this.Ok(questions);
}
like image 26
BenjaminPaul Avatar answered Sep 18 '22 14:09

BenjaminPaul