1

I would like to include stuctured data as a parameter to my HTTP GET call and think I have it set up correctly, but my API is not receiving the data as I expected. How do I set up both sides to communicate the structured data?

My angular application is asking a complicated question to the REST API written in Web API 2.

The controller method is defined as:

[RoutePrefix("v1/questions")]
public class VersionsController : ApiController
{
    [Route("askComplicated")]
    [HttpGet]
    [ResponseType(typeof(ComplicatedResponseDto))]
    public IHttpActionResult AskComplicatedQuestion(ComplicatedRequestDto complicatedRequest)
    {
        var responseElements = new List<ComplicatedResponseElementDto>();
        foreach (var requestElement in complicatedRequest.Elements)
        {
            responseElements.Add(new ComplicatedResponseElementDto()
            {
                Id = requestElement.Id,
                answer = "it is unknowable!!!"
            });
        }
        return Ok(new ComplicatedResponseDto() { Elements = responseElements.ToArray()});
    }

The DTOs:

public class ComplicatedRequestDto
{
    public ComplicatedRequestElementDto[] Elements { get; set; }
}

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


public class ComplicatedResponseDto
{
    public ComplicatedResponseElementDto[] Elements { get; set; }
}

public class ComplicatedResponseElementDto
{
    public int Id { get; set; }
    public string Answer { get; set; }

}

I broke it down this way because I like a simple request and a simple response. I'm adopting the patterns that worked best for my past WCF work (and understand that might be my problem here).

From the angular side, here is my code:

    var request = $http({
        method: "get",
        url: "http://localhost:65520/v1/questions/askComplicated",
        data: {
            complicatedRequest : {
                elements: [
                  { id: 2, question: 'what is the meaning of life?' },
                  { id: 3, question: 'why am I here?' },
                  { id: 4, question: 'what stock should I pick?' }
                ]
            }
        }
    });
    return request.then(handleSuccess, handleError);

When I call the REST API from my angular application, the WEB API 2 application receives it, but the ComplicatedRequestDto is null. How do I properly send that data so it will go through?

2 Answers 2

1

Update your API from Get to Post, because when we want to pass complex object it contains more data and we have restrictions to send maximum characters in URL. Do below modifications:

[RoutePrefix("v1/questions")]
public class VersionsController : ApiController
{
    [Route("askComplicated")]
    [HttpPost]
    [ResponseType(typeof(ComplicatedResponseDto))]
    public IHttpActionResult AskComplicatedQuestion([FromBody]ComplicatedRequestDto complicatedRequest)
    {
        //write ur code here...
    }
}

Update your js code as below:

 var request = $http({
        method: "post",
        url: "http://localhost:65520/v1/questions/askComplicated",  
        data: {
            complicatedRequest : {
                elements: [
                  { id: 2, question: 'what is the meaning of life?' },
                  { id: 3, question: 'why am I here?' },
                  { id: 4, question: 'what stock should I pick?' }
                ]
            },
        }
    });
    return request.then(handleSuccess, handleError);
Sign up to request clarification or add additional context in comments.

2 Comments

when I do that it returns 405 method not allowed.
that works for me now that I look at it again. Thanks!
0

You should add [FromUri] anotation before the method parameter to inform WebAPI that you want to load this parameter from the application Uri, and this is where your data goes when you use GET http action with data parameter.

So your code should look like this

[RoutePrefix("v1/questions")]
public class VersionsController : ApiController
{
    [Route("askComplicated")]
    [HttpGet]
    [ResponseType(typeof(ComplicatedResponseDto))]
    public IHttpActionResult AskComplicatedQuestion([FromUri]ComplicatedRequestDto complicatedRequest)
    {
        var responseElements = new List<ComplicatedResponseElementDto>();
        foreach (var requestElement in complicatedRequest.Elements)
        {
            responseElements.Add(new ComplicatedResponseElementDto()
            {
                Id = requestElement.Id,
                answer = "it is unknowable!!!"
            });
        }
        return Ok(new ComplicatedResponseDto() { Elements = responseElements.ToArray()});
    }

You also have to correct the payload to match stucture of your classes. The corect value should look like this:

{
  "Elements": [
    {
      "Id": 1,
      "Question": "sample string 2"
    },
    {
      "Id": 1,
      "Question": "sample string 2"
    }
  ]
}

And finally to provide the JavaScript code example it will be like (I only have jQuery, but payload will be the same for Angular):

$.ajax({url:"/v1/questions/askComplicated",data: {
  "Elements": [
    {
      "Id": 2,
      "Question": "what is the meaning of life?"
    },
    {
      "Id": 3,
      "Question": "why am I here?"
    }
  ]
}})

2 Comments

After making that change the request is still null. I'll research mofre about FromUri to see if I did something wrong.
Hi Michael, please check my updated answer. It should be working now. In JS part of your code you had extra fields, so the ASP was not able to deserialize you object. So you need to add FromUri anotation and fix JS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.