简体   繁体   中英

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 ie api/questions/2 ==> gives me back all the questions with questionnaireId = 2.

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM