Rick
Rick

Reputation: 1274

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.

Upvotes: 11

Views: 32974

Answers (4)

CodeCaster
CodeCaster

Reputation: 151594

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);

Upvotes: 12

BenjaminPaul
BenjaminPaul

Reputation: 2931

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);
}

Upvotes: 6

Jazjef
Jazjef

Reputation: 481

First of all do not use the entity directly for providing data. Create a DTO for your entities:

public class QuestionDto
{

  public int id {get; set;}
  //put here getter and setter for all other Question attributes you want to have

  public QuestionDto(Question question){
    this.id = question.id;
    ... and so on
  }
}

Then your GET method could look like this:

// GET: api/Questions/5
public List<QuestionDto> GetQuestion(int questionnaireId)
{
    IEnumerable<QuestionDto> questions = from q in db.Questions
    where q.QuestionnaireId == questionnaireId
    select new QuestionDto(q);
    return questions.toList();
}

I also recommend to use JSON for data transfer since it is quite ease to use with Javascript.

Upvotes: 1

webcodervk
webcodervk

Reputation: 145

I think that you are looking for some code similar to below:

public IEnumerable<Question> Get(int id)
    {
        //Create the list that you need to return here
        // I am creating a new list and adding an object below just for 
        // explaining the idea.

        var questions = new List<Question>();
        questions.Add(new Question());
        return questions;
    }

Upvotes: 0

Related Questions